<!DOCTYPE html><html lang="zh-CN" data-theme="light"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"><title>react入门基础篇 | 七里香</title><meta name="keywords" content="react"><meta name="author" content="william"><meta name="copyright" content="william"><meta name="format-detection" content="telephone=no"><meta name="theme-color" content="#ffffff"><meta name="description" content="介绍用于动态构建用户界面的 JavaScript 库(只关注于视图)  发送请求获取数据 处理数据（过滤，整理格式等） 操作DOM呈现页面（React做的事情）React是一个将数据渲染为HTML视图的开源JavaScript库  1.2 原生JavaScript的缺点 原生JavaScript操作DOM繁琐，效率低（DOM-API操作UI） 使用JavaScript直接操作DOM，浏览器会进行大">
<meta property="og:type" content="article">
<meta property="og:title" content="react入门基础篇">
<meta property="og:url" content="http://yokeney.gitee.io/my-hexo-blog/2021/01/15/react/index.html">
<meta property="og:site_name" content="七里香">
<meta property="og:description" content="介绍用于动态构建用户界面的 JavaScript 库(只关注于视图)  发送请求获取数据 处理数据（过滤，整理格式等） 操作DOM呈现页面（React做的事情）React是一个将数据渲染为HTML视图的开源JavaScript库  1.2 原生JavaScript的缺点 原生JavaScript操作DOM繁琐，效率低（DOM-API操作UI） 使用JavaScript直接操作DOM，浏览器会进行大">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="http://yokeney.gitee.io/my-hexo-blog/img/react.png">
<meta property="article:published_time" content="2021-01-15T07:58:33.000Z">
<meta property="article:modified_time" content="2022-10-15T13:05:01.840Z">
<meta property="article:author" content="william">
<meta property="article:tag" content="react">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="http://yokeney.gitee.io/my-hexo-blog/img/react.png"><link rel="shortcut icon" href="/my-hexo-blog/img/index.ico"><link rel="canonical" href="http://yokeney.gitee.io/my-hexo-blog/2021/01/15/react/"><link rel="preconnect" href="//cdn.jsdelivr.net"/><link rel="preconnect" href="//busuanzi.ibruce.info"/><link rel="stylesheet" href="/my-hexo-blog/css/index.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free/css/all.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox.min.css" media="print" onload="this.media='all'"><script>const GLOBAL_CONFIG = { 
  root: '/my-hexo-blog/',
  algolia: undefined,
  localSearch: {"path":"/my-hexo-blog/search.xml","preload":false,"languages":{"hits_empty":"找不到您查询的内容：${query}"}},
  translate: undefined,
  noticeOutdate: undefined,
  highlight: {"plugin":"highlighjs","highlightCopy":true,"highlightLang":true,"highlightHeightLimit":false},
  copy: {
    success: '复制成功',
    error: '复制错误',
    noSupport: '浏览器不支持'
  },
  relativeDate: {
    homepage: false,
    post: false
  },
  runtime: '',
  date_suffix: {
    just: '刚刚',
    min: '分钟前',
    hour: '小时前',
    day: '天前',
    month: '个月前'
  },
  copyright: undefined,
  lightbox: 'fancybox',
  Snackbar: undefined,
  source: {
    justifiedGallery: {
      js: 'https://cdn.jsdelivr.net/npm/flickr-justified-gallery/dist/fjGallery.min.js',
      css: 'https://cdn.jsdelivr.net/npm/flickr-justified-gallery/dist/fjGallery.min.css'
    }
  },
  isPhotoFigcaption: false,
  islazyload: false,
  isAnchor: false
}</script><script id="config-diff">var GLOBAL_CONFIG_SITE = {
  title: 'react入门基础篇',
  isPost: true,
  isHome: false,
  isHighlightShrink: false,
  isToc: true,
  postUpdate: '2022-10-15 21:05:01'
}</script><noscript><style type="text/css">
  #nav {
    opacity: 1
  }
  .justified-gallery img {
    opacity: 1
  }

  #recent-posts time,
  #post-meta time {
    display: inline !important
  }
</style></noscript><script>(win=>{
    win.saveToLocal = {
      set: function setWithExpiry(key, value, ttl) {
        if (ttl === 0) return
        const now = new Date()
        const expiryDay = ttl * 86400000
        const item = {
          value: value,
          expiry: now.getTime() + expiryDay,
        }
        localStorage.setItem(key, JSON.stringify(item))
      },

      get: function getWithExpiry(key) {
        const itemStr = localStorage.getItem(key)

        if (!itemStr) {
          return undefined
        }
        const item = JSON.parse(itemStr)
        const now = new Date()

        if (now.getTime() > item.expiry) {
          localStorage.removeItem(key)
          return undefined
        }
        return item.value
      }
    }
  
    win.getScript = url => new Promise((resolve, reject) => {
      const script = document.createElement('script')
      script.src = url
      script.async = true
      script.onerror = reject
      script.onload = script.onreadystatechange = function() {
        const loadState = this.readyState
        if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
        script.onload = script.onreadystatechange = null
        resolve()
      }
      document.head.appendChild(script)
    })
  
      win.activateDarkMode = function () {
        document.documentElement.setAttribute('data-theme', 'dark')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#0d0d0d')
        }
      }
      win.activateLightMode = function () {
        document.documentElement.setAttribute('data-theme', 'light')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#ffffff')
        }
      }
      const t = saveToLocal.get('theme')
    
          if (t === 'dark') activateDarkMode()
          else if (t === 'light') activateLightMode()
        
      const asideStatus = saveToLocal.get('aside-status')
      if (asideStatus !== undefined) {
        if (asideStatus === 'hide') {
          document.documentElement.classList.add('hide-aside')
        } else {
          document.documentElement.classList.remove('hide-aside')
        }
      }
    
    const detectApple = () => {
      if(/iPad|iPhone|iPod|Macintosh/.test(navigator.userAgent)){
        document.documentElement.classList.add('apple')
      }
    }
    detectApple()
    })(window)</script><meta name="generator" content="Hexo 6.3.0"></head><body><div id="web_bg"></div><div id="sidebar"><div id="menu-mask"></div><div id="sidebar-menus"><div class="avatar-img is-center"><img src="/my-hexo-blog/img/2.png" onerror="onerror=null;src='/img/friend_404.gif'" alt="avatar"/></div><div class="sidebar-site-data site-data is-center"><a href="/my-hexo-blog/archives/"><div class="headline">文章</div><div class="length-num">17</div></a><a href="/my-hexo-blog/tags/"><div class="headline">标签</div><div class="length-num">13</div></a><a href="/my-hexo-blog/categories/"><div class="headline">分类</div><div class="length-num">0</div></a></div><hr/><div class="menus_items"><div class="menus_item"><a class="site-page" href="/my-hexo-blog/"><i class="fa-fw iconfont icon-shouyex"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page group" href="javascript:void(0);"><i class="fa-fw iconfont icon-zuixinwenzhang_huaban"></i><span> 分类</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child" href="/my-hexo-blog/vueResources/"><i class="fa-fw iconfont icon-fenlei1"></i><span> vue</span></a></li><li><a class="site-page child" href="/my-hexo-blog/reactResources/"><i class="fa-fw iconfont icon-fenlei1"></i><span> react</span></a></li></ul></div><div class="menus_item"><a class="site-page group" href="javascript:void(0);"><i class="fa-fw iconfont icon-shenghuo"></i><span> 后台</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child" href="/my-hexo-blog/nodeResources/"><i class="fa-fw iconfont icon-fenlei1"></i><span> node</span></a></li></ul></div></div></div></div><div class="post" id="body-wrap"><header class="post-bg" id="page-header" style="background-image: url('/my-hexo-blog/img/react.png')"><nav id="nav"><span id="blog_name"><a id="site-name" href="/my-hexo-blog/">七里香</a></span><div id="menus"><div id="search-button"><a class="site-page social-icon search"><i class="fas fa-search fa-fw"></i><span> 搜索</span></a></div><div class="menus_items"><div class="menus_item"><a class="site-page" href="/my-hexo-blog/"><i class="fa-fw iconfont icon-shouyex"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page group" href="javascript:void(0);"><i class="fa-fw iconfont icon-zuixinwenzhang_huaban"></i><span> 分类</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child" href="/my-hexo-blog/vueResources/"><i class="fa-fw iconfont icon-fenlei1"></i><span> vue</span></a></li><li><a class="site-page child" href="/my-hexo-blog/reactResources/"><i class="fa-fw iconfont icon-fenlei1"></i><span> react</span></a></li></ul></div><div class="menus_item"><a class="site-page group" href="javascript:void(0);"><i class="fa-fw iconfont icon-shenghuo"></i><span> 后台</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child" href="/my-hexo-blog/nodeResources/"><i class="fa-fw iconfont icon-fenlei1"></i><span> node</span></a></li></ul></div></div><div id="toggle-menu"><a class="site-page"><i class="fas fa-bars fa-fw"></i></a></div></div></nav><div id="post-info"><h1 class="post-title">react入门基础篇</h1><div id="post-meta"><div class="meta-firstline"><span class="post-meta-date"><i class="far fa-calendar-alt fa-fw post-meta-icon"></i><span class="post-meta-label">发表于</span><time class="post-meta-date-created" datetime="2021-01-15T07:58:33.000Z" title="发表于 2021-01-15 15:58:33">2021-01-15</time><span class="post-meta-separator">|</span><i class="fas fa-history fa-fw post-meta-icon"></i><span class="post-meta-label">更新于</span><time class="post-meta-date-updated" datetime="2022-10-15T13:05:01.840Z" title="更新于 2022-10-15 21:05:01">2022-10-15</time></span></div><div class="meta-secondline"><span class="post-meta-separator">|</span><span class="post-meta-pv-cv" id="" data-flag-title="react入门基础篇"><i class="far fa-eye fa-fw post-meta-icon"></i><span class="post-meta-label">阅读量:</span><span id="busuanzi_value_page_pv"><i class="fa-solid fa-spinner fa-spin"></i></span></span></div></div></div></header><main class="layout" id="content-inner"><div id="post"><article class="post-content" id="article-container"><h2 id="介绍"><a href="#介绍" class="headerlink" title="介绍"></a>介绍</h2><p>用于动态构建用户界面的 JavaScript 库(只关注于视图)</p>
<ol>
<li>发送请求获取数据</li>
<li>处理数据（过滤，整理格式等）</li>
<li><strong>操作DOM呈现页面</strong>（React做的事情）<br>React是一个将数据渲染为HTML视图的开源JavaScript库</li>
</ol>
<h2 id="1-2-原生JavaScript的缺点"><a href="#1-2-原生JavaScript的缺点" class="headerlink" title="1.2 原生JavaScript的缺点"></a>1.2 原生JavaScript的缺点</h2><ol>
<li>原生JavaScript操作DOM繁琐，效率低（DOM-API操作UI）</li>
<li>使用JavaScript直接操作DOM，浏览器会进行大量的<strong>重绘重排</strong></li>
<li>原生JavaScript没有<strong>组件化</strong>编码方案，代码复用率很低</li>
</ol>
<p>【补充】<strong>浏览器重绘重排</strong></p>
<p>浏览器重绘(repaint)重排(reflow)与优化[浏览器机制]</p>
<ul>
<li>重绘(repaint)：当一个元素的外观发生改变，但没有改变布局,重新把元素外观绘制出来的过程，叫做重绘</li>
<li>重排(reflow)：当DOM的变化影响了元素的几何信息(DOM对象的位置和尺寸大小)，浏览器需要重新计算元素的几何属性，将其安放在界面中的正确位置，这个过程叫做重排</li>
</ul>
<h3 id="【补充】模块化与组件化"><a href="#【补充】模块化与组件化" class="headerlink" title="【补充】模块化与组件化"></a>【补充】模块化与组件化</h3><h4 id="模块"><a href="#模块" class="headerlink" title="模块"></a>模块</h4><p>理解：向外提供特定功能的js程序, 一般就是一个js文件<br>为什么要拆成模块：随着业务逻辑增加，代码越来越多且复杂。<br>作用：复用js, 简化js的编写, 提高js运行效率<br>组件<br>理解：用来实现局部功能效果的代码和资源的集合(html&#x2F;css&#x2F;js&#x2F;image等等)<br>为什么要用组件： 一个界面的功能更复杂<br>作用：复用编码, 简化项目编码, 提高运行效率</p>
<ul>
<li>模块化：当应用的js都以模块来编写的, 这个应用就是一个模块化的应用</li>
<li>组件化：当应用是以多组件的方式实现, 这个应用就是一个组件化的应用</li>
</ul>
<h3 id="React的特点"><a href="#React的特点" class="headerlink" title="React的特点"></a>React的特点</h3><p>采用组件化模式、声明式编码，提高开发效率及组件复用率<br>在 React Native中可以使用React语法进行移动端开发<br>使用虚拟DOM+Diff算法，尽量减少与真实DOM的交互</p>
<h3 id="React高效的原因"><a href="#React高效的原因" class="headerlink" title="React高效的原因"></a>React高效的原因</h3><p>使用虚拟(virtual)DOM, 不总是直接操作页面真实DOM。<br>DOM Diffing算法, 最小化页面重绘。<br>相关库介绍<br>旧版本 16.8.4 (March 5, 2019)<br>新版本 有不一样的会说明</p>
<p>react.js：React核心库。<br>react-dom.js：提供操作DOM的React扩展库。<br>babel.min.js：解析JSX语法代码转为JS代码的库。</p>
<p>【补充】babel.js的作用<br>浏览器不能直接解析JSX代码, 需要babel转译为纯JS的代码才能运行<br>只要用了JSX，都要加上<code>type=&quot;text/babel&quot;</code>, 声明需要babel来处理</p>
<h2 id="使用JSX创建虚拟DOM"><a href="#使用JSX创建虚拟DOM" class="headerlink" title="使用JSX创建虚拟DOM"></a>使用JSX创建虚拟DOM</h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> <span class="variable constant_">VDOM</span> = <span class="language-xml"><span class="tag">&lt;<span class="name">h1</span>&gt;</span>Hello,React<span class="tag">&lt;/<span class="name">h1</span>&gt;</span></span></span><br></pre></td></tr></table></figure>
<p>渲染虚拟DOM(元素)</p>
<ol>
<li>语法: ReactDOM.render(virtualDOM, containerDOM)</li>
<li>作用: 将虚拟DOM元素渲染到页面中的真实容器DOM中显示<br>参数说明</li>
</ol>
<ul>
<li>参数一: 纯js或jsx创建的虚拟dom对象</li>
<li>参数二: 用来包含虚拟DOM元素的真实dom元素对象(一般是一个div)<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;!DOCTYPE <span class="keyword">html</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">html</span> <span class="attr">lang</span>=<span class="string">&quot;en&quot;</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">head</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">meta</span> <span class="attr">charset</span>=<span class="string">&quot;UTF-8&quot;</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">title</span>&gt;</span>hello_react<span class="tag">&lt;/<span class="name">title</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line">  <span class="comment">&lt;!-- 准备好一个“容器” --&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;test&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"></span><br><span class="line">  <span class="comment">&lt;!-- 引入react核心库 --&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">script</span> <span class="attr">type</span>=<span class="string">&quot;text/javascript&quot;</span> <span class="attr">src</span>=<span class="string">&quot;../js/react.development.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line">  <span class="comment">&lt;!-- 引入react-dom，用于支持react操作DOM --&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">script</span> <span class="attr">type</span>=<span class="string">&quot;text/javascript&quot;</span> <span class="attr">src</span>=<span class="string">&quot;../js/react-dom.development.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line">  <span class="comment">&lt;!-- 引入babel，用于将jsx转为js --&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">script</span> <span class="attr">type</span>=<span class="string">&quot;text/javascript&quot;</span> <span class="attr">src</span>=<span class="string">&quot;../js/babel.min.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"></span><br><span class="line">  <span class="tag">&lt;<span class="name">script</span> <span class="attr">type</span>=<span class="string">&quot;text/babel&quot;</span>&gt;</span><span class="language-javascript"> <span class="comment">/* 此处一定要写babel */</span></span></span><br><span class="line"><span class="language-javascript">		<span class="comment">//1.创建虚拟DOM</span></span></span><br><span class="line"><span class="language-javascript">		<span class="keyword">const</span> <span class="variable constant_">VDOM</span> = <span class="language-xml"><span class="tag">&lt;<span class="name">h1</span>&gt;</span>Hello,React<span class="tag">&lt;/<span class="name">h1</span>&gt;</span></span> <span class="comment">/* 此处一定不要写引号，因为不是字符串 */</span></span></span><br><span class="line"><span class="language-javascript">		<span class="comment">//2.渲染虚拟DOM到页面</span></span></span><br><span class="line"><span class="language-javascript">		<span class="title class_">ReactDOM</span>.<span class="title function_">render</span>(<span class="variable constant_">VDOM</span>,<span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;test&#x27;</span>))</span></span><br><span class="line"><span class="language-javascript">	</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre></td></tr></table></figure></li>
</ul>
<p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/bffc46e61cf04c279582774265ce9cfc~tplv-k3u1fbpfcp-watermark.image" alt="image.png"></p>
<h1 id="创建虚拟DOM的两种方式"><a href="#创建虚拟DOM的两种方式" class="headerlink" title="创建虚拟DOM的两种方式"></a>创建虚拟DOM的两种方式</h1><h2 id="3-1-纯JS方式-一般不用"><a href="#3-1-纯JS方式-一般不用" class="headerlink" title="3.1 纯JS方式(一般不用)"></a>3.1 纯JS方式(一般不用)</h2><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;test&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">type</span>=<span class="string">&quot;text/javascript&quot;</span> <span class="attr">src</span>=<span class="string">&quot;../js/react.development.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">type</span>=<span class="string">&quot;text/javascript&quot;</span> <span class="attr">src</span>=<span class="string">&quot;../js/react-dom.development.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">type</span>=<span class="string">&quot;text/javascript&quot;</span> &gt;</span><span class="language-javascript"> </span></span><br><span class="line"><span class="language-javascript">	<span class="comment">//1.创建虚拟DOM</span></span></span><br><span class="line"><span class="language-javascript">	<span class="keyword">const</span> <span class="variable constant_">VDOM</span> = <span class="title class_">React</span>.<span class="title function_">createElement</span>(<span class="string">&#x27;h1&#x27;</span>,&#123;<span class="attr">id</span>:<span class="string">&#x27;title&#x27;</span>&#125;,<span class="title class_">React</span>.<span class="title function_">createElement</span>(<span class="string">&#x27;span&#x27;</span>,&#123;&#125;,<span class="string">&#x27;Hello,React&#x27;</span>))</span></span><br><span class="line"><span class="language-javascript">	<span class="comment">//2.渲染虚拟DOM到页面</span></span></span><br><span class="line"><span class="language-javascript">	<span class="title class_">ReactDOM</span>.<span class="title function_">render</span>(<span class="variable constant_">VDOM</span>,<span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;test&#x27;</span>))</span></span><br><span class="line"><span class="language-javascript"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure>
<h2 id="JSX方式"><a href="#JSX方式" class="headerlink" title="JSX方式"></a>JSX方式</h2><p>JSX方式就是js创建虚拟DOM的语法糖</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">&lt;div id=<span class="string">&quot;test&quot;</span>&gt;&lt;/div&gt;</span><br><span class="line"></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">script</span> <span class="attr">type</span>=<span class="string">&quot;text/javascript&quot;</span> <span class="attr">src</span>=<span class="string">&quot;../js/react.development.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">script</span> <span class="attr">type</span>=<span class="string">&quot;text/javascript&quot;</span> <span class="attr">src</span>=<span class="string">&quot;../js/react-dom.development.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">script</span> <span class="attr">type</span>=<span class="string">&quot;text/javascript&quot;</span> <span class="attr">src</span>=<span class="string">&quot;../js/babel.min.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">script</span> <span class="attr">type</span>=<span class="string">&quot;text/babel&quot;</span> &gt;</span><span class="language-javascript"> <span class="comment">/* 此处一定要写babel */</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">	<span class="comment">//1.创建虚拟DOM</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">	<span class="keyword">const</span> <span class="variable constant_">VDOM</span> = (  <span class="comment">/* 此处一定不要写引号，因为不是字符串 */</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">		<span class="language-xml"><span class="tag">&lt;<span class="name">h1</span> <span class="attr">id</span>=<span class="string">&quot;title&quot;</span>&gt;</span></span></span></span></span><br><span class="line"><span class="language-xml"><span class="language-javascript"><span class="language-xml">			<span class="tag">&lt;<span class="name">span</span>&gt;</span>Hello,React<span class="tag">&lt;/<span class="name">span</span>&gt;</span></span></span></span></span><br><span class="line"><span class="language-xml"><span class="language-javascript"><span class="language-xml">		<span class="tag">&lt;/<span class="name">h1</span>&gt;</span></span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">	)</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">	<span class="comment">//2.渲染虚拟DOM到页面</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">	<span class="title class_">ReactDOM</span>.<span class="title function_">render</span>(<span class="variable constant_">VDOM</span>,<span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;test&#x27;</span>))</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span></span><br></pre></td></tr></table></figure>

<p><img src="https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/52c94e72181c48bda06a89644cb02e6a~tplv-k3u1fbpfcp-watermark.image" alt="image.png"></p>
<h1 id="虚拟DOM与真实DOM"><a href="#虚拟DOM与真实DOM" class="headerlink" title="虚拟DOM与真实DOM"></a>虚拟DOM与真实DOM</h1><p>打印输出虚拟DOM和真实DOM进行比较</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">const VDOM = (  /* 此处一定不要写引号，因为不是字符串 */</span><br><span class="line">	<span class="tag">&lt;<span class="name">h1</span> <span class="attr">id</span>=<span class="string">&quot;title&quot;</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">span</span>&gt;</span>Hello,React<span class="tag">&lt;/<span class="name">span</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;/<span class="name">h1</span>&gt;</span></span><br><span class="line">)</span><br><span class="line">//2.渲染虚拟DOM到页面</span><br><span class="line">ReactDOM.render(VDOM,document.getElementById(&#x27;test&#x27;))</span><br><span class="line"></span><br><span class="line">const TDOM = document.getElementById(&#x27;demo&#x27;)</span><br><span class="line">console.log(&#x27;虚拟DOM&#x27;,VDOM);</span><br><span class="line">console.log(&#x27;真实DOM&#x27;,TDOM);</span><br><span class="line">debugger;</span><br></pre></td></tr></table></figure>

<p><img src="https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/78505a9467724985869d80f9f047be3d~tplv-k3u1fbpfcp-watermark.image" alt="image.png"></p>
<p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ef87a4c0e30a44b185b404adff596a22~tplv-k3u1fbpfcp-watermark.image" alt="image.png"></p>
<ol>
<li><strong>虚拟DOM本质是Object类型的对象（一般对象）</strong></li>
<li><strong>虚拟DOM比较“轻”，真实DOM比较“重”，因为虚拟DOM是React内部在用，无需真实DOM上那么多的属性</strong></li>
<li><strong>虚拟DOM最终会被React转化为真实DOM，呈现在页面上</strong></li>
</ol>
<h1 id="JSX入门"><a href="#JSX入门" class="headerlink" title="JSX入门"></a>JSX入门</h1><p>概述<br>全称: JavaScript XML<br>React定义的一种类似于XML的JS扩展语法: JS + XML本质是React.createElement(component, props, …children)方法的语法糖</p>
<p>作用: 用来简化创建虚拟DOM</p>
<p>写法：var ele &#x3D; <h1>Hello JSX!</h1></p>
<p><strong>注意1：它不是字符串, 也不是HTML&#x2F;XML标签</strong></p>
<p><strong>注意2：它最终产生的就是一个JS对象</strong><br>标签名任意: HTML标签或其它标签</p>
<p>标签属性任意: HTML标签属性或其它<br>基本语法规则</p>
<ul>
<li>定义虚拟DOM时，不要写引号。</li>
<li>标签中混入JS表达式时要用 <code>&#123; &#125;</code>。</li>
<li>样式的类名指定不要用 class，要用 className。（因为class是ES6中类的关键字，所以不让用）</li>
<li>内联样式，要用 <code>style=&#123;&#123; key:value &#125;&#125;</code> 的形式去写。</li>
<li>只有一个根标签</li>
<li>标签必须闭合</li>
<li>标签首字母</li>
<li>(1). 若小写字母开头，则将该标签转为html中同名元素，若html中无该标签对应的同名元素，则报错。</li>
<li>(2). 若大写字母开头，React就去渲染对应的组件，若组件没有定义，则报错。<br>补充】 区分js表达式与js语句<br>表达式：一个表达式会产生一个值，可以放在任何一个需要值的地方<br>下面这些都是表达式：<br>下面这些都是表达式：</li>
</ul>
<ol>
<li><code>a</code></li>
<li><code>a+b</code></li>
<li><code>demo(1)</code> &#x2F;&#x2F; 函数调用表达式</li>
<li><code>arr.map()</code></li>
<li><code>function test () &#123;&#125;</code></li>
<li>语句(代码)：</li>
<li>下面这些都是语句(代码)：</li>
<li><code>if()&#123; &#125;</code></li>
<li><code>for()&#123; &#125;</code></li>
<li><code>switch( )&#123;case:xxxx&#125;</code></li>
</ol>
<h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><ol>
<li>遇到 <code>&lt;</code> 开头的代码, 以标签的语法解析: html同名标签转换为html同名元素, 其它标签需要特别解析</li>
<li>遇到以 <code>&#123;</code> 开头的代码，以JS语法解析: 标签中的js表达式必须用<code>&#123; &#125;</code>包含</li>
</ol>
<h1 id="基本理解和使用"><a href="#基本理解和使用" class="headerlink" title="基本理解和使用"></a>基本理解和使用</h1><h2 id="函数式组件"><a href="#函数式组件" class="headerlink" title="函数式组件"></a>函数式组件</h2><figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 1. 创建函数式组件</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">MyComponent</span>(<span class="params"></span>)&#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>); <span class="comment">//此处的this是undefined，因为babel编译后开启了严格模式</span></span><br><span class="line">  <span class="keyword">return</span> <span class="language-xml"><span class="tag">&lt;<span class="name">h2</span>&gt;</span>我是用函数定义的组件（适用于简单组件的定义）<span class="tag">&lt;/<span class="name">h2</span>&gt;</span></span></span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// 2. 渲染组件到页面</span></span><br><span class="line"><span class="title class_">ReactDOM</span>.<span class="title function_">render</span>(<span class="language-xml"><span class="tag">&lt;<span class="name">MyComponent</span>/&gt;</span></span>, <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;test&#x27;</span>))</span><br></pre></td></tr></table></figure>

<p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/e0c862f85b5647cca943f054ac5b4980~tplv-k3u1fbpfcp-watermark.image" alt="image.png"><br>执行了<code>ReactDOM.render(&lt;MyComponent/&gt;.......</code>之后，发生了什么？</p>
<ol>
<li>React解析组件标签，找到了MyComponent组件。</li>
<li>发现组件是使用函数定义的，随后<strong>调用该函数</strong>，将返回的虚拟DOM转为真实DOM，随后呈现在页面中。</li>
</ol>
<h3 id="补充】严格模式中的this"><a href="#补充】严格模式中的this" class="headerlink" title="补充】严格模式中的this"></a>补充】严格模式中的this</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">sayThis</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>)</span><br><span class="line">&#125;</span><br><span class="line"><span class="title function_">sayThis</span>() <span class="comment">// Window &#123;...&#125;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">sayThis2</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="string">&#x27;use strict&#x27;</span></span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>)</span><br><span class="line">&#125;</span><br><span class="line"><span class="title function_">sayThis2</span>() <span class="comment">// undefined</span></span><br></pre></td></tr></table></figure>
<ul>
<li><code>如果不开启严格模式，直接调用函数，函数中的this指向window</code></li>
<li><code>如果开启了严格模式，直接调用函数，函数中的this是undefined</code></li>
</ul>
<h2 id="类式组件"><a href="#类式组件" class="headerlink" title="类式组件"></a>类式组件</h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//1.创建类式组件</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">MyComponent</span> <span class="keyword">extends</span> <span class="title class_ inherited__">React.Component</span> &#123;</span><br><span class="line">  <span class="title function_">render</span>(<span class="params"></span>)&#123;</span><br><span class="line">	<span class="comment">//render是放在哪里的？—— MyComponent的原型对象上，供实例使用。</span></span><br><span class="line">	<span class="comment">//render中的this是谁？—— MyComponent的实例对象 &lt;=&gt; MyComponent组件实例对象。</span></span><br><span class="line">	<span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;render中的this:&#x27;</span>,<span class="variable language_">this</span>);</span><br><span class="line">	<span class="keyword">return</span> <span class="language-xml"><span class="tag">&lt;<span class="name">h2</span>&gt;</span>我是用类定义的组件(适用于【复杂组件】的定义)<span class="tag">&lt;/<span class="name">h2</span>&gt;</span></span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//2.渲染组件到页面</span></span><br><span class="line"><span class="title class_">ReactDOM</span>.<span class="title function_">render</span>(<span class="language-xml"><span class="tag">&lt;<span class="name">MyComponent</span>/&gt;</span></span>,<span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;test&#x27;</span>))</span><br></pre></td></tr></table></figure>
<p><strong>执行了ReactDOM.render(<MyComponent/>…….之后，发生了什么？</strong></p>
<p><code>React解析组件标签，找到了MyComponent组件。 发现组件是使用类定义的，随后new出来该类的实例，并通过该实例调用到原型上的render方法。 将render返回的虚拟DOM转为真实DOM，随后呈现在页面中。</code></p>
<h3 id="【补充】关于ES6中类的注意事项"><a href="#【补充】关于ES6中类的注意事项" class="headerlink" title="【补充】关于ES6中类的注意事项"></a>【补充】关于ES6中类的注意事项</h3><ol>
<li>类中的构造器不是必须要写的，要对实例进行一些初始化的操作，如添加指定属性时才写。</li>
<li>如果A类继承了B类，且A类中写了构造器，那么A类构造器中的<code>super</code>是必须要调用的。</li>
<li>类中所定义的方法，都放在了类的原型对象上，供实例去使用。</li>
</ol>
<h2 id="注意"><a href="#注意" class="headerlink" title="注意"></a>注意</h2><ol>
<li>组件名必须<strong>首字母大写</strong></li>
<li>虚拟DOM元素只能有<strong>一个</strong>根元素</li>
<li>虚拟DOM元素必须有<strong>结束</strong>标签</li>
</ol>
<ul>
<li>重点关注下渲染类组件标签的基本流程</li>
</ul>
<ol>
<li>React内部会创建组件实例对象</li>
<li>调用<code>render()</code>得到虚拟DOM, 并解析为真实DOM</li>
<li>插入到指定的页面元素内部</li>
</ol>
<h1 id="组件实例的三大核心属性1-state-状态"><a href="#组件实例的三大核心属性1-state-状态" class="headerlink" title="组件实例的三大核心属性1: state 状态"></a>组件实例的三大核心属性1: <code>state</code> 状态</h1><h2 id="理解"><a href="#理解" class="headerlink" title="理解"></a>理解</h2><ol>
<li><code>state</code>是组件对象最重要的属性, 值是对象(可以包含多个<code>key-value</code>的组合)</li>
<li>组件被称为”状态机”, 通过更新组件的<code>state</code>来更新对应的页面显示(重新渲染组件)</li>
</ol>
<h4 id="补充】类中方法的this指向问题"><a href="#补充】类中方法的this指向问题" class="headerlink" title="补充】类中方法的this指向问题"></a>补充】类中方法的this指向问题</h4><ol>
<li>类中定义的方法，在内部默认开启了<strong>局部</strong>的严格模式\</li>
<li>开启严格模式，函数如果直接调用，this不会指向window，而是undefined<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Person</span> &#123;</span><br><span class="line">  <span class="title function_">constructor</span>(<span class="params">name,age</span>)&#123;</span><br><span class="line">	<span class="variable language_">this</span>.<span class="property">name</span> = name</span><br><span class="line">	<span class="variable language_">this</span>.<span class="property">age</span> = age</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="title function_">study</span>(<span class="params"></span>)&#123;</span><br><span class="line">	<span class="comment">//study方法放在了哪里？——类的原型对象上，供实例使用</span></span><br><span class="line">	<span class="comment">//通过Person实例调用study时，study中的this就是Person实例</span></span><br><span class="line">	<span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> p1 = <span class="keyword">new</span> <span class="title class_">Person</span>(<span class="string">&#x27;tom&#x27;</span>,<span class="number">18</span>)</span><br><span class="line">p1.<span class="title function_">study</span>() <span class="comment">//通过实例调用study方法  Person</span></span><br><span class="line"><span class="keyword">const</span> x = p1.<span class="property">study</span></span><br><span class="line"><span class="title function_">x</span>() <span class="comment">// 直接调用 undefined</span></span><br></pre></td></tr></table></figure>
注意</li>
</ol>
<ul>
<li>组件中render方法中的this为组件实例对象</li>
<li>组件自定义的方法中this为undefined，如何解决？</li>
<li>a) 强制绑定this: 通过函数对象的bind()</li>
<li>b) 箭头函数 + 赋值语句</li>
<li>状态数据state，不能直接修改或更新</li>
<li>状态必须通过setState()进行更新, 且更新是一种合并，不是替换。</li>
</ul>
<h1 id="组件实例的三大核心属性2-props"><a href="#组件实例的三大核心属性2-props" class="headerlink" title="组件实例的三大核心属性2: props"></a>组件实例的三大核心属性2: <code>props</code></h1><h2 id="理解-1"><a href="#理解-1" class="headerlink" title="理解"></a>理解</h2><ol>
<li>每个组件对象都会有<code>props</code>(properties的简写)属性</li>
<li>组件标签的所有属性都保存在<code>props</code>中</li>
</ol>
<h2 id="作用"><a href="#作用" class="headerlink" title="作用"></a>作用</h2><ol>
<li>通过标签属性从组件<strong>外</strong>向组件<strong>内</strong>传递变化的数据</li>
<li>注意: 组件内部<strong>不可修改</strong><code>props</code>数据，是只读的</li>
</ol>
<h2 id="使用指南"><a href="#使用指南" class="headerlink" title="使用指南"></a>使用指南</h2><h3 id="内部读取某个属性值"><a href="#内部读取某个属性值" class="headerlink" title="内部读取某个属性值"></a>内部读取某个属性值</h3><p><code>this.props.name</code></p>
<h3 id="扩展属性-将对象的所有属性通过props传递（批量传递标签属性）"><a href="#扩展属性-将对象的所有属性通过props传递（批量传递标签属性）" class="headerlink" title="扩展属性: 将对象的所有属性通过props传递（批量传递标签属性）"></a>扩展属性: 将对象的所有属性通过<code>props</code>传递（批量传递标签属性）</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="title class_">ReactDOM</span>.<span class="title function_">render</span>(<span class="language-xml"><span class="tag">&lt;<span class="name">Person</span> <span class="attr">name</span>=<span class="string">&quot;yk&quot;</span> <span class="attr">age</span>=<span class="string">&quot;18&quot;</span> <span class="attr">sex</span>=<span class="string">&quot;男&quot;</span>/&gt;</span></span>, <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;test&#x27;</span>))</span><br></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> person = &#123;<span class="attr">name</span>: <span class="string">&#x27;yk&#x27;</span>, <span class="attr">age</span>: <span class="number">18</span>, <span class="attr">sex</span>: <span class="string">&#x27;男&#x27;</span>&#125; <span class="title class_">ReactDOM</span>.<span class="title function_">render</span>(<span class="language-xml"><span class="tag">&lt;<span class="name">Person</span> &#123; <span class="attr">...person</span> &#125;/&gt;</span></span>, <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;test&#x27;</span>))</span><br></pre></td></tr></table></figure>
<h4 id="【补充】展开运算符"><a href="#【补充】展开运算符" class="headerlink" title="【补充】展开运算符"></a>【补充】展开运算符</h4><figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> arr1 = [<span class="number">1</span>, <span class="number">3</span>, <span class="number">5</span>, <span class="number">7</span>, <span class="number">9</span>]</span><br><span class="line"><span class="keyword">let</span> arr2 = [<span class="number">2</span>, <span class="number">4</span>, <span class="number">6</span>, <span class="number">8</span>, <span class="number">10</span>]</span><br><span class="line"><span class="comment">// 1. 展开一个数组</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(...arr1); <span class="comment">// 1 3 5 7 9</span></span><br><span class="line"><span class="comment">// 2. 连接数组</span></span><br><span class="line"><span class="keyword">let</span> arr3 = [...arr1, ...arr2]</span><br><span class="line"></span><br><span class="line"><span class="comment">// 3. 在函数中使用</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">sum</span>(<span class="params">...numbers</span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> numbers.<span class="title function_">reduce</span>(<span class="function">(<span class="params">preValue, currentValue</span>) =&gt;</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> preValue + currentValue</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">sum</span>(<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>)); <span class="comment">// 10</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 4. 构造字面量对象时使用展开语法</span></span><br><span class="line"><span class="keyword">let</span> person = &#123;</span><br><span class="line">  <span class="attr">name</span>: <span class="string">&#x27;tom&#x27;</span>,</span><br><span class="line">  <span class="attr">age</span>: <span class="number">18</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// console.log(...person); // 报错，展开运算符不能展开对象</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(&#123;...person&#125;) <span class="comment">// &#123;name: &quot;tom&quot;, age: 18&#125;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> person2 = &#123; ...person &#125; <span class="comment">// 可以拷贝一个对象</span></span><br><span class="line">person.<span class="property">name</span> = <span class="string">&#x27;jerry&#x27;</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(person2); <span class="comment">// &#123;name: &quot;tom&quot;, age: 18&#125;</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(person); <span class="comment">// &#123;name: &quot;jerry&quot;, age: 18&#125;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 5. 合并对象</span></span><br><span class="line"><span class="keyword">let</span> person3 = &#123;</span><br><span class="line">  ...person,</span><br><span class="line">  <span class="attr">name</span>: <span class="string">&#x27;jack&#x27;</span>,</span><br><span class="line">  <span class="attr">address</span>: <span class="string">&quot;地球&quot;</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(person3); <span class="comment">// &#123;name: &quot;jack&quot;, age: 18, address: &quot;地球&quot;&#125;</span></span><br></pre></td></tr></table></figure>
<h3 id="对props中的属性值进行类型限制和必要性限制"><a href="#对props中的属性值进行类型限制和必要性限制" class="headerlink" title="对props中的属性值进行类型限制和必要性限制"></a>对<code>props</code>中的属性值进行类型限制和必要性限制</h3><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!-- 引入prop-types，用于对组件标签属性进行限制 --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">type</span>=<span class="string">&quot;text/javascript&quot;</span> <span class="attr">src</span>=<span class="string">&quot;../js/prop-types.js&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//对标签属性进行类型、必要性的限制</span></span><br><span class="line"><span class="title class_">Person</span>.<span class="property">propTypes</span> = &#123;</span><br><span class="line">  <span class="attr">name</span>:<span class="title class_">PropTypes</span>.<span class="property">string</span>.<span class="property">isRequired</span>, <span class="comment">// 限制name必传，且为字符串</span></span><br><span class="line">  <span class="attr">sex</span>:<span class="title class_">PropTypes</span>.<span class="property">string</span>, <span class="comment">// 限制sex为字符串</span></span><br><span class="line">  <span class="attr">age</span>:<span class="title class_">PropTypes</span>.<span class="property">number</span>, <span class="comment">// 限制age为数值</span></span><br><span class="line">  <span class="attr">speak</span>:<span class="title class_">PropTypes</span>.<span class="property">func</span>, <span class="comment">// 限制speak为函数</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>可以写在类的里面，前面加<code>static</code>关键字</p>
<h3 id="默认属性值"><a href="#默认属性值" class="headerlink" title="默认属性值"></a>默认属性值</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//指定默认标签属性值</span></span><br><span class="line"><span class="title class_">Person</span>.<span class="property">defaultProps</span> = &#123;</span><br><span class="line">	<span class="attr">sex</span>:<span class="string">&#x27;男&#x27;</span>, <span class="comment">// sex默认值为男</span></span><br><span class="line">	<span class="attr">age</span>:<span class="number">18</span> <span class="comment">//age默认值为18</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h3 id="组件类的构造函数"><a href="#组件类的构造函数" class="headerlink" title="组件类的构造函数"></a>组件类的构造函数</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="title function_">constructor</span>(<span class="params">props</span>)&#123; <span class="variable language_">super</span>(props) <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>.<span class="property">props</span>)<span class="comment">//打印所有属性 &#125;</span></span><br></pre></td></tr></table></figure>

<p><img src="https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/837147102fd14df5ac63321abbb36a13~tplv-k3u1fbpfcp-watermark.image" alt="image.png"></p>
<p><strong>构造器是否接收<code>props</code>，是否传递给<code>super</code>，取决于：是否希望在构造器中通过<code>this</code>访问<code>props</code></strong></p>
<p>很多同学不知道这个为什么药使用super,是为了传递<strong>属性</strong></p>
<h2 id="函数式组件使用props"><a href="#函数式组件使用props" class="headerlink" title="函数式组件使用props"></a>函数式组件使用<code>props</code></h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//创建组件</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">Person</span> (props)&#123;</span><br><span class="line">  <span class="keyword">const</span> &#123;name,age,sex&#125; = props</span><br><span class="line">    <span class="keyword">return</span> (</span><br><span class="line">	  <span class="language-xml"><span class="tag">&lt;<span class="name">ul</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">	    <span class="tag">&lt;<span class="name">li</span>&gt;</span>姓名：&#123;name&#125;<span class="tag">&lt;/<span class="name">li</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">	    <span class="tag">&lt;<span class="name">li</span>&gt;</span>性别：&#123;sex&#125;<span class="tag">&lt;/<span class="name">li</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">	    <span class="tag">&lt;<span class="name">li</span>&gt;</span>年龄：&#123;age&#125;<span class="tag">&lt;/<span class="name">li</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">	  <span class="tag">&lt;/<span class="name">ul</span>&gt;</span></span></span><br><span class="line">	)</span><br><span class="line">&#125;</span><br><span class="line"><span class="title class_">Person</span>.<span class="property">propTypes</span> = &#123;</span><br><span class="line">  <span class="attr">name</span>:<span class="title class_">PropTypes</span>.<span class="property">string</span>.<span class="property">isRequired</span>, <span class="comment">//限制name必传，且为字符串</span></span><br><span class="line">  <span class="attr">sex</span>:<span class="title class_">PropTypes</span>.<span class="property">string</span>,  <span class="comment">//限制sex为字符串</span></span><br><span class="line">  <span class="attr">age</span>:<span class="title class_">PropTypes</span>.<span class="property">number</span>,  <span class="comment">//限制age为数值</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 指定默认标签属性值</span></span><br><span class="line"><span class="title class_">Person</span>.<span class="property">defaultProps</span> = &#123;</span><br><span class="line">  <span class="attr">sex</span>:<span class="string">&#x27;男&#x27;</span>,<span class="comment">// sex默认值为男</span></span><br><span class="line">  <span class="attr">age</span>:<span class="number">18</span> <span class="comment">// age默认值为18</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//渲染组件到页面</span></span><br><span class="line"><span class="title class_">ReactDOM</span>.<span class="title function_">render</span>(<span class="language-xml"><span class="tag">&lt;<span class="name">Person</span> <span class="attr">name</span>=<span class="string">&quot;jerry&quot;</span>/&gt;</span></span>,<span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;test1&#x27;</span>))</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h1 id="refs与事件处理"><a href="#refs与事件处理" class="headerlink" title="refs与事件处理"></a><code>refs</code>与事件处理</h1><h2 id="理解-2"><a href="#理解-2" class="headerlink" title="理解"></a>理解</h2><p>组件内的标签可以定义<code>ref</code>属性来标识自己</p>
<h2 id="编码"><a href="#编码" class="headerlink" title="编码"></a>编码</h2><h3 id="字符串形式的ref（新版本不推荐使用了）"><a href="#字符串形式的ref（新版本不推荐使用了）" class="headerlink" title="字符串形式的ref（新版本不推荐使用了）"></a>字符串形式的<code>ref</code>（新版本不推荐使用了）</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">&lt;input ref=<span class="string">&quot;input1&quot;</span>/&gt;</span><br><span class="line"><span class="variable language_">this</span>.<span class="property">refs</span>.<span class="property">input1</span></span><br></pre></td></tr></table></figure>
<h4 id="示例"><a href="#示例" class="headerlink" title="示例"></a>示例</h4><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//创建组件</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Demo</span> <span class="keyword">extends</span> <span class="title class_ inherited__">React.Component</span>&#123;</span><br><span class="line">  <span class="comment">//展示左侧输入框的数据</span></span><br><span class="line">  showData = <span class="function">()=&gt;</span>&#123;</span><br><span class="line">	<span class="keyword">const</span> &#123;input1&#125; = <span class="variable language_">this</span>.<span class="property">refs</span></span><br><span class="line">	<span class="title function_">alert</span>(input1.<span class="property">value</span>)</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">//展示右侧输入框的数据</span></span><br><span class="line">  showData2 = <span class="function">()=&gt;</span>&#123;</span><br><span class="line">	<span class="keyword">const</span> &#123;input2&#125; = <span class="variable language_">this</span>.<span class="property">refs</span></span><br><span class="line">	<span class="title function_">alert</span>(input2.<span class="property">value</span>)</span><br><span class="line">  &#125;</span><br><span class="line">  </span><br><span class="line">  <span class="title function_">render</span>(<span class="params"></span>)&#123;</span><br><span class="line">	<span class="keyword">return</span>(</span><br><span class="line">	  <span class="language-xml"><span class="tag">&lt;<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">	    <span class="tag">&lt;<span class="name">input</span> <span class="attr">ref</span>=<span class="string">&quot;input1&quot;</span> <span class="attr">type</span>=<span class="string">&quot;text&quot;</span> <span class="attr">placeholder</span>=<span class="string">&quot;点击按钮提示数据&quot;</span>/&gt;</span><span class="symbol">&amp;nbsp;</span></span></span><br><span class="line"><span class="language-xml">	    <span class="tag">&lt;<span class="name">button</span> <span class="attr">onClick</span>=<span class="string">&#123;this.showData&#125;</span>&gt;</span>点我提示左侧的数据<span class="tag">&lt;/<span class="name">button</span>&gt;</span><span class="symbol">&amp;nbsp;</span></span></span><br><span class="line"><span class="language-xml">	    <span class="tag">&lt;<span class="name">input</span> <span class="attr">ref</span>=<span class="string">&quot;input2&quot;</span> <span class="attr">onBlur</span>=<span class="string">&#123;this.showData2&#125;</span> <span class="attr">type</span>=<span class="string">&quot;text&quot;</span> <span class="attr">placeholder</span>=<span class="string">&quot;失去焦点提示数据&quot;</span>/&gt;</span></span></span><br><span class="line"><span class="language-xml">	  <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line">	)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//渲染组件到页面</span></span><br><span class="line"><span class="title class_">ReactDOM</span>.<span class="title function_">render</span>(<span class="language-xml"><span class="tag">&lt;<span class="name">Demo</span> /&gt;</span></span>,<span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;test&#x27;</span>))</span><br></pre></td></tr></table></figure>
<h3 id="回调形式的ref"><a href="#回调形式的ref" class="headerlink" title="回调形式的ref"></a>回调形式的<code>ref</code></h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&lt;input ref=&#123;<span class="function">(<span class="params">currentNode</span>)=&gt;</span>&#123;<span class="variable language_">this</span>.<span class="property">input1</span> = currentNode&#125;&#125; /&gt;</span><br><span class="line"><span class="comment">//简写</span></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">input</span> <span class="attr">ref</span>=<span class="string">&#123;</span> <span class="attr">c</span> =&gt;</span> this.input1 = c &#125; /&gt;</span></span><br></pre></td></tr></table></figure>
<h4 id="示例-1"><a href="#示例-1" class="headerlink" title="示例"></a>示例</h4><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//创建组件</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Demo</span> <span class="keyword">extends</span> <span class="title class_ inherited__">React.Component</span>&#123;</span><br><span class="line">  <span class="comment">//展示左侧输入框的数据</span></span><br><span class="line">  showData = <span class="function">()=&gt;</span>&#123;</span><br><span class="line">	<span class="keyword">const</span> &#123;input1&#125; = <span class="variable language_">this</span></span><br><span class="line">	<span class="title function_">alert</span>(input1.<span class="property">value</span>)</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">//展示右侧输入框的数据</span></span><br><span class="line">  showData2 = <span class="function">()=&gt;</span>&#123;</span><br><span class="line">	<span class="keyword">const</span> &#123;input2&#125; = <span class="variable language_">this</span></span><br><span class="line">	<span class="title function_">alert</span>(input2.<span class="property">value</span>)</span><br><span class="line">  &#125;</span><br><span class="line">  </span><br><span class="line">  <span class="title function_">render</span>(<span class="params"></span>)&#123;</span><br><span class="line">	<span class="keyword">return</span>(</span><br><span class="line">	  <span class="language-xml"><span class="tag">&lt;<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">		<span class="tag">&lt;<span class="name">input</span> <span class="attr">ref</span>=<span class="string">&#123;</span> <span class="attr">c</span> =&gt;</span> this.input1 = c &#125; type=&quot;text&quot; placeholder=&quot;点击按钮提示数据&quot;/&gt;<span class="symbol">&amp;nbsp;</span></span></span><br><span class="line"><span class="language-xml">		<span class="tag">&lt;<span class="name">button</span> <span class="attr">onClick</span>=<span class="string">&#123;this.showData&#125;</span>&gt;</span>点我提示左侧的数据<span class="tag">&lt;/<span class="name">button</span>&gt;</span><span class="symbol">&amp;nbsp;</span></span></span><br><span class="line"><span class="language-xml">		<span class="tag">&lt;<span class="name">input</span> <span class="attr">onBlur</span>=<span class="string">&#123;this.showData2&#125;</span> <span class="attr">ref</span>=<span class="string">&#123;c</span> =&gt;</span> this.input2 = c &#125; type=&quot;text&quot; placeholder=&quot;失去焦点提示数据&quot;/&gt;<span class="symbol">&amp;nbsp;</span></span></span><br><span class="line"><span class="language-xml">	  <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line">	)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//渲染组件到页面</span></span><br><span class="line"><span class="title class_">ReactDOM</span>.<span class="title function_">render</span>(<span class="language-xml"><span class="tag">&lt;<span class="name">Demo</span> /&gt;</span></span>,<span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;test&#x27;</span>))</span><br></pre></td></tr></table></figure>
<h4 id="回调执行次数"><a href="#回调执行次数" class="headerlink" title="回调执行次数"></a>回调执行次数</h4><p>内联的回调，渲染时调用一次，每次更新都会执行两次<br>类绑定的回调，就在初始渲染时调用一次<br>影响不大，日常开发基本都用<strong>内联</strong>，方便一点</p>
<h3 id="createRef创建ref容器"><a href="#createRef创建ref容器" class="headerlink" title="createRef创建ref容器"></a><code>createRef</code>创建<code>ref</code>容器</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// React.createRef调用后可以返回一个容器 // 该容器可以存储被ref所标识的节点,该容器是“专人专用”的 </span></span><br><span class="line">myRef = <span class="title class_">React</span>.<span class="title function_">createRef</span>() &lt;input ref=&#123;<span class="variable language_">this</span>.<span class="property">myRef</span>&#125;/&gt;</span><br></pre></td></tr></table></figure>
<h4 id="使用"><a href="#使用" class="headerlink" title="使用"></a>使用</h4><p><code>this.myRef.current</code></p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//创建组件</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Demo</span> <span class="keyword">extends</span> <span class="title class_ inherited__">React.Component</span>&#123;</span><br><span class="line"></span><br><span class="line">  myRef = <span class="title class_">React</span>.<span class="title function_">createRef</span>()</span><br><span class="line">  myRef2 = <span class="title class_">React</span>.<span class="title function_">createRef</span>()</span><br><span class="line">  <span class="comment">//展示左侧输入框的数据</span></span><br><span class="line">  showData = <span class="function">()=&gt;</span>&#123;</span><br><span class="line">	<span class="title function_">alert</span>(<span class="variable language_">this</span>.<span class="property">myRef</span>.<span class="property">current</span>.<span class="property">value</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">//展示右侧输入框的数据</span></span><br><span class="line">  showData2 = <span class="function">()=&gt;</span>&#123;</span><br><span class="line">	<span class="title function_">alert</span>(<span class="variable language_">this</span>.<span class="property">myRef2</span>.<span class="property">current</span>.<span class="property">value</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  </span><br><span class="line">  <span class="title function_">render</span>(<span class="params"></span>)&#123;</span><br><span class="line">	<span class="keyword">return</span>(</span><br><span class="line">	  <span class="language-xml"><span class="tag">&lt;<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">		<span class="tag">&lt;<span class="name">input</span> <span class="attr">ref</span>=<span class="string">&#123;this.myRef&#125;</span> <span class="attr">type</span>=<span class="string">&quot;text&quot;</span> <span class="attr">placeholder</span>=<span class="string">&quot;点击按钮提示数据&quot;</span>/&gt;</span><span class="symbol">&amp;nbsp;</span></span></span><br><span class="line"><span class="language-xml">		<span class="tag">&lt;<span class="name">button</span> <span class="attr">onClick</span>=<span class="string">&#123;this.showData&#125;</span>&gt;</span>点我提示左侧的数据<span class="tag">&lt;/<span class="name">button</span>&gt;</span><span class="symbol">&amp;nbsp;</span></span></span><br><span class="line"><span class="language-xml">		<span class="tag">&lt;<span class="name">input</span> <span class="attr">onBlur</span>=<span class="string">&#123;this.showData2&#125;</span> <span class="attr">ref</span>=<span class="string">&#123;this.myRef2&#125;</span> <span class="attr">type</span>=<span class="string">&quot;text&quot;</span> <span class="attr">placeholder</span>=<span class="string">&quot;失去焦点提示数据&quot;</span>/&gt;</span><span class="symbol">&amp;nbsp;</span></span></span><br><span class="line"><span class="language-xml">	  <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line">	)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//渲染组件到页面</span></span><br><span class="line"><span class="title class_">ReactDOM</span>.<span class="title function_">render</span>(<span class="language-xml"><span class="tag">&lt;<span class="name">Demo</span> /&gt;</span></span>,<span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;test&#x27;</span>))</span><br></pre></td></tr></table></figure>
<h3 id="React中的事件处理"><a href="#React中的事件处理" class="headerlink" title="React中的事件处理"></a>React中的事件处理</h3><ol>
<li>通过onXxx属性指定事件处理函数(注意大小写)</li>
<li>React使用的是自定义(合成)事件, 而不是使用的原生DOM事件—-为了更好的兼容性</li>
<li>React中的事件是通过事件委托方式处理的(委托给组件最外层的元素) —-为了的高效</li>
<li>通过event.target得到发生事件的DOM元素对象—-不要过度使用ref</li>
</ol>
<h1 id="收集表单数据"><a href="#收集表单数据" class="headerlink" title="收集表单数据"></a>收集表单数据</h1><h2 id="理解-3"><a href="#理解-3" class="headerlink" title="理解"></a>理解</h2><ol>
<li>受控组件</li>
<li>非受控组件</li>
</ol>
<h2 id="非受控组件"><a href="#非受控组件" class="headerlink" title="非受控组件"></a>非受控组件</h2><p>页面中所有输入类DOM的值，都是现用现取的</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 创建组件</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Login</span> <span class="keyword">extends</span> <span class="title class_ inherited__">React.Component</span> &#123;</span><br><span class="line">  handleSubmit = <span class="function">(<span class="params">event</span>) =&gt;</span> &#123;</span><br><span class="line">    event.<span class="title function_">preventDefault</span>() <span class="comment">// 阻止表单提交</span></span><br><span class="line">    <span class="keyword">const</span> &#123;username, password&#125; = <span class="variable language_">this</span></span><br><span class="line">    <span class="title function_">alert</span>(<span class="string">`您输入的用户名是 <span class="subst">$&#123;username.value&#125;</span>，您输入的密码是：<span class="subst">$&#123;password.value&#125;</span>`</span>)</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="title function_">render</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> (</span><br><span class="line">      <span class="language-xml"><span class="tag">&lt;<span class="name">form</span> <span class="attr">action</span>=<span class="string">&quot;https://www.baidu.com/&quot;</span> <span class="attr">onSubmit</span>=<span class="string">&#123;this.handleSubmit&#125;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        用户名：<span class="tag">&lt;<span class="name">input</span> <span class="attr">ref</span>=<span class="string">&#123;c</span> =&gt;</span> this.username = c&#125; type=&quot;text&quot; name=&quot;username&quot; /&gt;</span></span><br><span class="line"><span class="language-xml">        密码：<span class="tag">&lt;<span class="name">input</span> <span class="attr">ref</span>=<span class="string">&#123;c</span> =&gt;</span> this.password = c&#125; type=&quot;password&quot; name=&quot;password&quot; /&gt;</span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">button</span>&gt;</span>登录<span class="tag">&lt;/<span class="name">button</span>&gt;</span>  </span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;/<span class="name">form</span>&gt;</span></span></span><br><span class="line">    )</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// 渲染组件</span></span><br><span class="line"><span class="title class_">ReactDOM</span>.<span class="title function_">render</span>(<span class="language-xml"><span class="tag">&lt;<span class="name">Login</span> /&gt;</span></span>, <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;test&#x27;</span>))</span><br></pre></td></tr></table></figure>
<h2 id="受控组件"><a href="#受控组件" class="headerlink" title="受控组件"></a>受控组件</h2><p>页面中输入类的DOM，随着输入的过程，将数据存储在状态<code>state</code>中，需要用的时候在从状态<code>state</code>中取（有点类似Vue中的双向数据绑定）</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 创建组件</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Login</span> <span class="keyword">extends</span> <span class="title class_ inherited__">React.Component</span> &#123;</span><br><span class="line">  <span class="comment">// 初始化状态</span></span><br><span class="line">  state = &#123;</span><br><span class="line">    <span class="attr">username</span>: <span class="string">&#x27;&#x27;</span>,</span><br><span class="line">    <span class="attr">password</span>: <span class="string">&#x27;&#x27;</span></span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">// 保存用户名到状态中</span></span><br><span class="line">  saveUsername = <span class="function">(<span class="params">event</span>) =&gt;</span> &#123;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="title function_">setState</span>(&#123;<span class="attr">username</span>: event.<span class="property">target</span>.<span class="property">value</span>&#125;)</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">// 保存密码到状态中</span></span><br><span class="line">  savePassword = <span class="function">(<span class="params">event</span>) =&gt;</span> &#123;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="title function_">setState</span>(&#123;<span class="attr">password</span>: event.<span class="property">target</span>.<span class="property">value</span>&#125;)</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">// 表单提交的回调</span></span><br><span class="line">  handleSubmit = <span class="function">(<span class="params">event</span>) =&gt;</span> &#123;</span><br><span class="line">    event.<span class="title function_">preventDefault</span>()</span><br><span class="line">    <span class="keyword">const</span> &#123;username, password&#125; = <span class="variable language_">this</span>.<span class="property">state</span></span><br><span class="line">    <span class="title function_">alert</span>(<span class="string">`您输入的用户名是 <span class="subst">$&#123;username&#125;</span>，您输入的密码是：<span class="subst">$&#123;password&#125;</span>`</span>)</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="title function_">render</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> (</span><br><span class="line">      <span class="language-xml"><span class="tag">&lt;<span class="name">form</span> <span class="attr">action</span>=<span class="string">&quot;https://www.baidu.com/&quot;</span> <span class="attr">onSubmit</span>=<span class="string">&#123;this.handleSubmit&#125;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        用户名：<span class="tag">&lt;<span class="name">input</span> <span class="attr">onChange</span>=<span class="string">&#123;this.saveUsername&#125;</span> <span class="attr">type</span>=<span class="string">&quot;text&quot;</span> <span class="attr">name</span>=<span class="string">&quot;username&quot;</span> /&gt;</span></span></span><br><span class="line"><span class="language-xml">        密码：<span class="tag">&lt;<span class="name">input</span> <span class="attr">onChange</span>=<span class="string">&#123;this.savePassword&#125;</span> <span class="attr">type</span>=<span class="string">&quot;password&quot;</span> <span class="attr">name</span>=<span class="string">&quot;password&quot;</span> /&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">button</span>&gt;</span>登录<span class="tag">&lt;/<span class="name">button</span>&gt;</span>  </span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;/<span class="name">form</span>&gt;</span></span></span><br><span class="line">    )</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// 渲染组件</span></span><br><span class="line"><span class="title class_">ReactDOM</span>.<span class="title function_">render</span>(<span class="language-xml"><span class="tag">&lt;<span class="name">Login</span> /&gt;</span></span>, <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;test&#x27;</span>))</span><br></pre></td></tr></table></figure>
<h1 id="高阶函数与函数的柯里化"><a href="#高阶函数与函数的柯里化" class="headerlink" title="高阶函数与函数的柯里化"></a>高阶函数与函数的柯里化</h1><h3 id="高阶函数"><a href="#高阶函数" class="headerlink" title="高阶函数"></a>高阶函数</h3><ul>
<li>高阶函数：如果一个函数符合下面2个规范中的任何一个，那该函数就是高阶函数。</li>
<li>若A函数，接收的参数是一个函数，那么A就可以称之为高阶函数。</li>
<li>若A函数，调用的返回值依然是一个函数，那么A就可以称之为高阶函数。</li>
<li>常见的高阶函数有：Promise、setTimeout、arr.map()等等</li>
</ul>
<h2 id="函数的柯里化"><a href="#函数的柯里化" class="headerlink" title="函数的柯里化"></a>函数的柯里化</h2><p><strong>函数的柯里化</strong>：通过函数调用继续返回函数的方式，实现多次接收参数最后统一处理的函数编码形式。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">sum1</span>(<span class="params">a, b, c</span>)&#123;</span><br><span class="line">  <span class="keyword">return</span> a + b + c;</span><br><span class="line">&#125;</span><br><span class="line"><span class="title function_">sum1</span>(<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 柯里化后</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">sum</span>(<span class="params">a</span>)&#123;</span><br><span class="line">  <span class="keyword">return</span><span class="function">(<span class="params">b</span>)=&gt;</span>&#123;</span><br><span class="line">	<span class="keyword">return</span> <span class="function">(<span class="params">c</span>)=&gt;</span>&#123;</span><br><span class="line">	  <span class="keyword">return</span> a+b+c</span><br><span class="line">	&#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="title function_">sum</span>(<span class="number">1</span>)(<span class="number">2</span>)(<span class="number">3</span>)</span><br></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//创建组件</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Login</span> <span class="keyword">extends</span> <span class="title class_ inherited__">React.Component</span>&#123;</span><br><span class="line">  <span class="comment">//初始化状态</span></span><br><span class="line">  state = &#123;</span><br><span class="line">    <span class="attr">username</span>:<span class="string">&#x27;&#x27;</span>, <span class="comment">//用户名</span></span><br><span class="line">    <span class="attr">password</span>:<span class="string">&#x27;&#x27;</span> <span class="comment">//密码</span></span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">//保存表单数据到状态中 （高阶函数+函数柯里化）</span></span><br><span class="line">  saveFormData = <span class="function">(<span class="params">dataType</span>)=&gt;</span>&#123;</span><br><span class="line">	<span class="keyword">return</span> <span class="function">(<span class="params">event</span>)=&gt;</span>&#123;</span><br><span class="line">	  <span class="variable language_">this</span>.<span class="title function_">setState</span>(&#123;[dataType]:event.<span class="property">target</span>.<span class="property">value</span>&#125;)</span><br><span class="line">	&#125;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">//表单提交的回调</span></span><br><span class="line">  handleSubmit = <span class="function">(<span class="params">event</span>)=&gt;</span>&#123;</span><br><span class="line">	event.<span class="title function_">preventDefault</span>() <span class="comment">//阻止表单提交</span></span><br><span class="line">	<span class="keyword">const</span> &#123;username,password&#125; = <span class="variable language_">this</span>.<span class="property">state</span></span><br><span class="line">	<span class="title function_">alert</span>(<span class="string">`你输入的用户名是：<span class="subst">$&#123;username&#125;</span>,你输入的密码是：<span class="subst">$&#123;password&#125;</span>`</span>)</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="title function_">render</span>(<span class="params"></span>)&#123;</span><br><span class="line">	<span class="keyword">return</span>(</span><br><span class="line">	  <span class="language-xml"><span class="tag">&lt;<span class="name">form</span> <span class="attr">onSubmit</span>=<span class="string">&#123;this.handleSubmit&#125;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">		用户名：<span class="tag">&lt;<span class="name">input</span> <span class="attr">onChange</span>=<span class="string">&#123;this.saveFormData(</span>&#x27;<span class="attr">username</span>&#x27;)&#125; <span class="attr">type</span>=<span class="string">&quot;text&quot;</span> <span class="attr">name</span>=<span class="string">&quot;username&quot;</span>/&gt;</span></span></span><br><span class="line"><span class="language-xml">		密码：<span class="tag">&lt;<span class="name">input</span> <span class="attr">onChange</span>=<span class="string">&#123;this.saveFormData(</span>&#x27;<span class="attr">password</span>&#x27;)&#125; <span class="attr">type</span>=<span class="string">&quot;password&quot;</span> <span class="attr">name</span>=<span class="string">&quot;password&quot;</span>/&gt;</span></span></span><br><span class="line"><span class="language-xml">		<span class="tag">&lt;<span class="name">button</span>&gt;</span>登录<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">	  <span class="tag">&lt;/<span class="name">form</span>&gt;</span></span></span><br><span class="line">	)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//渲染组件</span></span><br><span class="line"><span class="title class_">ReactDOM</span>.<span class="title function_">render</span>(<span class="language-xml"><span class="tag">&lt;<span class="name">Login</span>/&gt;</span></span>,<span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;test&#x27;</span>))</span><br></pre></td></tr></table></figure>
<h1 id="组件的生命周期"><a href="#组件的生命周期" class="headerlink" title="组件的生命周期"></a>组件的生命周期</h1><h2 id="理解-4"><a href="#理解-4" class="headerlink" title="理解"></a>理解</h2><ol>
<li>组件从创建到死亡它会经历一些特定的阶段。</li>
<li>React组件中包含一系列勾子函数(生命周期回调函数), 会在特定的时刻调用。</li>
<li>我们在定义组件时，会在特定的生命周期回调函数中，做特定的工作。</li>
</ol>
<h2 id="引入案例"><a href="#引入案例" class="headerlink" title="引入案例"></a>引入案例</h2><p>需求:定义组件实现以下功能：</p>
<ol>
<li>让指定的文本做显示 &#x2F; 隐藏的渐变动画</li>
<li>从完全可见，到彻底消失，耗时2S</li>
<li>点击“不活了”按钮从界面中卸载组件</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//创建组件</span></span><br><span class="line"><span class="comment">//生命周期回调函数 &lt;=&gt; 生命周期钩子函数 &lt;=&gt; 生命周期函数 &lt;=&gt; 生命周期钩子</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Life</span> <span class="keyword">extends</span> <span class="title class_ inherited__">React.Component</span>&#123;</span><br><span class="line"></span><br><span class="line">  state = &#123;<span class="attr">opacity</span>:<span class="number">1</span>&#125;</span><br><span class="line"></span><br><span class="line">  death = <span class="function">()=&gt;</span>&#123;</span><br><span class="line">	<span class="comment">//卸载组件</span></span><br><span class="line">	<span class="title class_">ReactDOM</span>.<span class="title function_">unmountComponentAtNode</span>(<span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;test&#x27;</span>))</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">//组件挂完毕</span></span><br><span class="line">  <span class="title function_">componentDidMount</span>(<span class="params"></span>)&#123;</span><br><span class="line">	<span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;componentDidMount&#x27;</span>);</span><br><span class="line">	<span class="variable language_">this</span>.<span class="property">timer</span> = <span class="built_in">setInterval</span>(<span class="function">() =&gt;</span> &#123;</span><br><span class="line">	  <span class="comment">//获取原状态</span></span><br><span class="line">	  <span class="keyword">let</span> &#123;opacity&#125; = <span class="variable language_">this</span>.<span class="property">state</span></span><br><span class="line">	  <span class="comment">//减小0.1</span></span><br><span class="line">	  opacity -= <span class="number">0.1</span></span><br><span class="line">	  <span class="keyword">if</span>(opacity &lt;= <span class="number">0</span>) opacity = <span class="number">1</span></span><br><span class="line">	  <span class="comment">//设置新的透明度</span></span><br><span class="line">	  <span class="variable language_">this</span>.<span class="title function_">setState</span>(&#123;opacity&#125;)</span><br><span class="line">	&#125;, <span class="number">200</span>);</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">//组件将要卸载</span></span><br><span class="line">  <span class="title function_">componentWillUnmount</span>(<span class="params"></span>)&#123;</span><br><span class="line">	<span class="comment">//清除定时器</span></span><br><span class="line">	<span class="built_in">clearInterval</span>(<span class="variable language_">this</span>.<span class="property">timer</span>)</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">//初始化渲染、状态更新之后</span></span><br><span class="line">  <span class="title function_">render</span>(<span class="params"></span>)&#123;</span><br><span class="line">	<span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;render&#x27;</span>);</span><br><span class="line">	<span class="keyword">return</span>(</span><br><span class="line">	  <span class="language-xml"><span class="tag">&lt;<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">	    <span class="tag">&lt;<span class="name">h2</span> <span class="attr">style</span>=<span class="string">&#123;&#123;opacity:this.state.opacity&#125;&#125;</span>&gt;</span>React学不会怎么办？<span class="tag">&lt;/<span class="name">h2</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">	    <span class="tag">&lt;<span class="name">button</span> <span class="attr">onClick</span>=<span class="string">&#123;this.death&#125;</span>&gt;</span>不活了<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">	  <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line">	)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//渲染组件</span></span><br><span class="line"><span class="title class_">ReactDOM</span>.<span class="title function_">render</span>(<span class="language-xml"><span class="tag">&lt;<span class="name">Life</span>/&gt;</span></span>,<span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;test&#x27;</span>))</span><br></pre></td></tr></table></figure>
<h2 id="生命周期的三个阶段（旧）"><a href="#生命周期的三个阶段（旧）" class="headerlink" title="生命周期的三个阶段（旧）"></a>生命周期的三个阶段（旧）</h2><p><img src="https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/20c5722a932942a1b296c520d0ff2698~tplv-k3u1fbpfcp-watermark.image" alt="20210608114316605.png"><br>初始化阶段</p>
<ul>
<li>由ReactDOM.render()触发—初次渲染</li>
<li>constructor() —— 类组件中的构造函数</li>
<li>componentWillMount() —— 组件将要挂载 【即将废弃】</li>
<li>render() —— 挂载组件</li>
<li>componentDidMount() —— 组件挂载完成 比较常用</li>
<li>一般在这个钩子中做一些初始化的事，例如：开启定时器、发送网络请求、订阅消息<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Count</span> <span class="keyword">extends</span> <span class="title class_ inherited__">React.Component</span>&#123;</span><br><span class="line">  <span class="comment">// 构造器</span></span><br><span class="line">  <span class="title function_">constructor</span>(<span class="params">props</span>)&#123;</span><br><span class="line">    <span class="title function_">alert</span>(<span class="string">&#x27;constructor&#x27;</span>)</span><br><span class="line">	<span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;Count---constructor&#x27;</span>);</span><br><span class="line">	<span class="variable language_">super</span>(props)</span><br><span class="line">	<span class="comment">//初始化状态</span></span><br><span class="line">	<span class="variable language_">this</span>.<span class="property">state</span> = &#123;<span class="attr">count</span>:<span class="number">0</span>&#125;</span><br><span class="line">  &#125;</span><br><span class="line">  add = <span class="function">() =&gt;</span> &#123;</span><br><span class="line">    <span class="keyword">const</span> &#123;count&#125; = <span class="variable language_">this</span>.<span class="property">state</span></span><br><span class="line">    <span class="variable language_">this</span>.<span class="title function_">setState</span>(&#123;<span class="attr">count</span>: count+<span class="number">1</span>&#125;)</span><br><span class="line">  &#125;</span><br><span class="line">  </span><br><span class="line">  <span class="comment">//组件将要挂载的钩子</span></span><br><span class="line">  <span class="title function_">componentWillMount</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="title function_">alert</span>(<span class="string">&#x27;componentWillMount&#x27;</span>)</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;Count---componentWillMount&#x27;</span>);</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="title function_">render</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="title function_">alert</span>(<span class="string">&#x27;render&#x27;</span>)</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;Count---render&#x27;</span>);</span><br><span class="line">    <span class="keyword">const</span> &#123;count&#125; = <span class="variable language_">this</span>.<span class="property">state</span></span><br><span class="line">    <span class="keyword">return</span>(</span><br><span class="line">      <span class="language-xml"><span class="tag">&lt;<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">h1</span>&gt;</span>当前计数值：&#123;count&#125;<span class="tag">&lt;/<span class="name">h1</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">button</span> <span class="attr">onClick</span>=<span class="string">&#123;this.add&#125;</span>&gt;</span>点我+1<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line">    )</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">//组件挂载完毕的钩子</span></span><br><span class="line">  <span class="title function_">componentDidMount</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="title function_">alert</span>(<span class="string">&#x27;componentDidMount&#x27;</span>)</span><br><span class="line">	<span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;Count---componentDidMount&#x27;</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="title class_">ReactDOM</span>.<span class="title function_">render</span>(<span class="language-xml"><span class="tag">&lt;<span class="name">Count</span>/&gt;</span></span>, <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;test&#x27;</span>))</span><br></pre></td></tr></table></figure></li>
</ul>
<p><strong>更新阶段【第一种情况】父组件重新render触发</strong></p>
<p>componentWillReceiveProps() —— 接收属性参数（非首次）【即将废弃】<br>然后调用下面的钩子函数</p>
<p><strong>【第二种情况】由组件内部this.setSate()</strong></p>
<p>shouldComponentUpdate() —— 组件是否应该被更新（默认返回true）<br>然后调用下面的钩子函数</p>
<p><strong>【第三种情况】强制更新 forceUpdate()</strong></p>
<p>componentWillUpdate() ——组件将要更新 【即将废弃】<br>render() —— 组件更新<br>componentDidUpdate() —— 组件完成更新</p>
<h3 id="卸载组件"><a href="#卸载组件" class="headerlink" title="卸载组件"></a>卸载组件</h3><p>由<code>ReactDOM.unmountComponentAtNode()</code>触发</p>
<ol>
<li><code>componentWillUnmount()</code> —— 组件即将卸载</li>
</ol>
<h2 id="生命周期的三个阶段（新）"><a href="#生命周期的三个阶段（新）" class="headerlink" title="生命周期的三个阶段（新）"></a>生命周期的三个阶段（新）</h2><p><img src="https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/770ef082a3ff4a6b868c230145f705ee~tplv-k3u1fbpfcp-watermark.image" alt="image.png"></p>
<h4 id="更新阶段"><a href="#更新阶段" class="headerlink" title="更新阶段"></a>更新阶段</h4><ul>
<li>由组件内部this.setSate()或父组件重新render触发或强制更新forceUpdate()</li>
<li>getDerivedStateFromProps() —— 从props得到一个派生的状态 【新增】</li>
<li>shouldComponentUpdate() —— 组件是否应该被更新（默认返回true）</li>
<li>render() —— 挂载组件</li>
<li>getSnapshotBeforeUpdate() —— 在更新之前获取快照【新增】</li>
<li>componentDidUpdate(prevProps, prevState, snapshotValue) —— 组件完成更新</li>
</ul>
<ol start="3">
<li>卸载组件</li>
</ol>
<ul>
<li>由ReactDOM.unmountComponentAtNode()触发</li>
<li>componentWillUnmount() —— 组件即将卸载</li>
</ul>
<h2 id="重要的勾子"><a href="#重要的勾子" class="headerlink" title="重要的勾子"></a>重要的勾子</h2><ol>
<li><code>render</code>：初始化渲染或更新渲染调用</li>
<li><code>componentDidMount</code>：开启监听, 发送ajax请求</li>
<li><code>componentWillUnmount</code>：做一些收尾工作, 如: 清理定时器</li>
</ol>
<h2 id="即将废弃的勾子"><a href="#即将废弃的勾子" class="headerlink" title="即将废弃的勾子"></a>即将废弃的勾子</h2><ol>
<li><code>componentWillMount</code></li>
<li><code>componentWillReceiveProps</code></li>
<li><code>componentWillUpdate</code></li>
</ol>
<p>现在使用会出现警告，下一个大版本需要加上<code>UNSAFE_</code>前缀才能使用，以后可能会被彻底废弃，不建议使用。</p>
<h1 id="虚拟DOM与DOM-Diffing算法"><a href="#虚拟DOM与DOM-Diffing算法" class="headerlink" title="虚拟DOM与DOM Diffing算法"></a>虚拟DOM与DOM Diffing算法</h1><h2 id="基本原理图"><a href="#基本原理图" class="headerlink" title="基本原理图"></a>基本原理图</h2><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/071c6df30e1744e192e81088711b1d09~tplv-k3u1fbpfcp-watermark.image" alt="image.png"></p>
<h2 id="关于key的经典面试题"><a href="#关于key的经典面试题" class="headerlink" title="关于key的经典面试题"></a>关于key的经典面试题</h2><p> react&#x2F;vue中的key有什么作用？（key的内部原理是什么？）<br> 为什么遍历列表时，key最好不要用index?<br>虚拟DOM中key的作用<br> 简单的说: key是虚拟DOM对象的标识, 在更新显示时key起着极其重要的作用。</p>
<p> 详细的说: 当状态中的数据发生变化时，react会根据【新数据】生成【新的虚拟DOM】, 随后React进行【新虚拟DOM】与【旧虚拟DOM】的diff比较，比较规则如下：</p>
<ul>
<li>旧虚拟DOM中找到了与新虚拟DOM相同的key：<ul>
<li><pre><code>(1).若虚拟DOM中内容没变, 直接使用之前的真实DOM
</code></pre>
</li>
<li><pre><code>(2).若虚拟DOM中内容变了, 则生成新的真实DOM，随后替换掉页面中之前的真实DOM
</code></pre>
</li>
</ul>
</li>
<li>旧虚拟DOM中未找到与新虚拟DOM相同的key<ul>
<li><pre><code>根据数据创建新的真实DOM，随后渲染到到页面
</code></pre>
</li>
</ul>
</li>
</ul>
<h4 id="用index作为key可能会引发的问题"><a href="#用index作为key可能会引发的问题" class="headerlink" title="用index作为key可能会引发的问题"></a>用index作为key可能会引发的问题</h4><p>若对数据进行：逆序添加、逆序删除等破坏顺序操作:<br>会产生没有必要的真实DOM更新 &#x3D;&#x3D;&gt; 界面效果没问题, 但效率低</p>
<p>如果结构中还包含输入类的DOM：<br>会产生错误DOM更新 &#x3D;&#x3D;&gt; 界面有问题</p>
<p>注意！如果不存在对数据的逆序添加、逆序删除等破坏顺序操作，<br>仅用于渲染列表用于展示，使用index作为key是没有问题的</p>
<h2 id="SPA的理解"><a href="#SPA的理解" class="headerlink" title="SPA的理解"></a>SPA的理解</h2><ol>
<li>单页Web应用（single page web application，<code>SPA</code>）</li>
<li>整个应用只有一个完整的页面。</li>
<li>点击页面中的链接不会刷新页面，只会做页面的局部更新。</li>
<li>数据都需要通过<code>ajax</code>请求获取, 并在前端异步展现。</li>
</ol>
<h2 id="路由的理解"><a href="#路由的理解" class="headerlink" title="路由的理解"></a>路由的理解</h2><h3 id="什么是路由"><a href="#什么是路由" class="headerlink" title="什么是路由?"></a>什么是路由?</h3><ol>
<li>一个路由就是一个映射关系(<code>key: value</code>)</li>
<li><code>key</code>为路径, <code>value</code>可能是<code>function</code>或<code>component</code></li>
</ol>
<h3 id="路由分类"><a href="#路由分类" class="headerlink" title="路由分类"></a>路由分类</h3><h4 id="后端路由"><a href="#后端路由" class="headerlink" title="后端路由"></a>后端路由</h4><ol>
<li>理解： <code>value</code>是<code>function</code>, 用来处理客户端提交的请求。</li>
<li>注册路由： <code>router.get(path, function(req, res))</code></li>
<li>工作过程：当<code>node</code>接收到一个请求时, 根据请求路径找到匹配的路由, 调用路由中的函数来处理请求, 返回响应数据</li>
</ol>
<h4 id="前端路由"><a href="#前端路由" class="headerlink" title="前端路由"></a>前端路由</h4><ol>
<li>浏览器端路由，value是<code>component</code>，用于展示页面内容。</li>
<li>注册路由: <code>&lt;Route path=&quot;/test&quot; component=&#123;Test&#125;&gt;</code></li>
<li>工作过程：当浏览器的<code>path</code>变为<code>/test</code>时, 当前路由组件就会变为<code>Test</code>组件</li>
</ol>
<h2 id="react-router-dom-的理解"><a href="#react-router-dom-的理解" class="headerlink" title="react-router-dom 的理解"></a><a target="_blank" rel="noopener" href="https://so.csdn.net/so/search?from=pc_blog_highlight&q=react">react</a>-router-dom 的理解</h2><ol>
<li><code>React</code>的一个插件库。</li>
<li>专门用来实现一个SPA应用。</li>
<li>基于<code>React</code>的项目基本都会用到此库。</li>
</ol>
<h1 id="react-router-dom相关API"><a href="#react-router-dom相关API" class="headerlink" title="react-router-dom相关API"></a>react-router-dom相关API</h1><h2 id="内置组件"><a href="#内置组件" class="headerlink" title="内置组件"></a>内置组件</h2><ol>
<li><code>&lt;BrowserRouter&gt;</code></li>
<li><code>&lt;HashRouter&gt;</code></li>
<li><code>&lt;Route&gt;</code></li>
<li><code>&lt;Redirect&gt;</code></li>
<li><code>&lt;Link&gt;</code></li>
<li><code>&lt;NavLink&gt;</code></li>
<li><code>&lt;Switch&gt;</code></li>
</ol>
<h2 id="其它"><a href="#其它" class="headerlink" title="其它"></a>其它</h2><ol>
<li><code>history</code>对象</li>
<li><code>match</code>对象</li>
<li><code>withRouter</code>函数</li>
</ol>
<h1 id="基本路由使用"><a href="#基本路由使用" class="headerlink" title="基本路由使用"></a>基本路由使用</h1><h2 id="效果"><a href="#效果" class="headerlink" title="效果"></a>效果</h2><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f304b8da020540349edf82b6c9494557~tplv-k3u1fbpfcp-watermark.image" alt="2021061416445215.gif"></p>
<h2 id="准备"><a href="#准备" class="headerlink" title="准备"></a>准备</h2><ol>
<li>下载react-router-dom: <code>npm install react-router-dom</code><br><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/fa3f07a7ff4d423cbeb0e80d67e224c5~tplv-k3u1fbpfcp-zoom-1.image" alt="在这里插入图片描述"></li>
<li>引入bootstrap.css: <code>&lt;link rel=&quot;stylesheet&quot; href=&quot;/css/bootstrap.css&quot;&gt;</code></li>
</ol>
<h2 id="路由的基本使用"><a href="#路由的基本使用" class="headerlink" title="路由的基本使用"></a>路由的基本使用</h2><p>明确好界面中的导航区、展示区<br>导航区的a标签改为Link标签<br><code>&lt;Link to=&quot;/xxxxx&quot;&gt;Demo&lt;/Link&gt;</code><br>展示区写Route标签进行路径的匹配</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">&lt;<span class="title class_">Route</span> path=<span class="string">&#x27;/xxxx&#x27;</span> component=&#123;<span class="title class_">Demo</span>&#125;/&gt;</span><br><span class="line">&lt;<span class="title class_">App</span>&gt;的最外侧包裹了一个&lt;<span class="title class_">BrowserRouter</span>&gt;或&lt;<span class="title class_">HashRouter</span>&gt;</span><br></pre></td></tr></table></figure>
<h2 id="实现"><a href="#实现" class="headerlink" title="实现"></a>实现</h2><h3 id="index-js"><a href="#index-js" class="headerlink" title="index.js"></a>index.js</h3><p>这里用一个标签将整个App包起来，保证使用的是同一个路由器</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//引入react核心库</span></span><br><span class="line"><span class="keyword">import</span> <span class="title class_">React</span> <span class="keyword">from</span> <span class="string">&#x27;react&#x27;</span></span><br><span class="line"><span class="comment">//引入ReactDOM</span></span><br><span class="line"><span class="keyword">import</span> <span class="title class_">ReactDOM</span> <span class="keyword">from</span> <span class="string">&#x27;react-dom&#x27;</span></span><br><span class="line"><span class="comment">//</span></span><br><span class="line"><span class="keyword">import</span> &#123;<span class="title class_">BrowserRouter</span>&#125; <span class="keyword">from</span> <span class="string">&#x27;react-router-dom&#x27;</span></span><br><span class="line"><span class="comment">//引入App</span></span><br><span class="line"><span class="keyword">import</span> <span class="title class_">App</span> <span class="keyword">from</span> <span class="string">&#x27;./App&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="title class_">ReactDOM</span>.<span class="title function_">render</span>(</span><br><span class="line">	<span class="language-xml"><span class="tag">&lt;<span class="name">BrowserRouter</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">		<span class="tag">&lt;<span class="name">App</span>/&gt;</span></span></span><br><span class="line"><span class="language-xml">	<span class="tag">&lt;/<span class="name">BrowserRouter</span>&gt;</span></span>,</span><br><span class="line">	<span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;root&#x27;</span>)</span><br><span class="line">)</span><br></pre></td></tr></table></figure>
<h3 id="App-jsx"><a href="#App-jsx" class="headerlink" title="App.jsx"></a>App.jsx</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> <span class="title class_">React</span>, &#123; <span class="title class_">Component</span> &#125; <span class="keyword">from</span> <span class="string">&#x27;react&#x27;</span></span><br><span class="line"><span class="keyword">import</span> &#123; <span class="title class_">Link</span>,<span class="title class_">Route</span> &#125; <span class="keyword">from</span> <span class="string">&#x27;react-router-dom&#x27;</span></span><br><span class="line"><span class="keyword">import</span> <span class="title class_">Home</span> <span class="keyword">from</span> <span class="string">&#x27;./Home&#x27;</span></span><br><span class="line"><span class="keyword">import</span> <span class="title class_">About</span> <span class="keyword">from</span> <span class="string">&#x27;./About&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="keyword">class</span> <span class="title class_">App</span> <span class="keyword">extends</span> <span class="title class_ inherited__">Component</span> &#123;</span><br><span class="line">  <span class="title function_">render</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> (</span><br><span class="line">      <span class="language-xml"><span class="tag">&lt;<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;<span class="name">div</span> <span class="attr">className</span>=<span class="string">&quot;row&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">div</span> <span class="attr">className</span>=<span class="string">&quot;col-xs-offset-2 col-xs-8&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;<span class="name">div</span> <span class="attr">className</span>=<span class="string">&quot;page-header&quot;</span>&gt;</span><span class="tag">&lt;<span class="name">h2</span>&gt;</span>React Router Demo<span class="tag">&lt;/<span class="name">h2</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;<span class="name">div</span> <span class="attr">className</span>=<span class="string">&quot;row&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">div</span> <span class="attr">className</span>=<span class="string">&quot;col-xs-2 col-xs-offset-2&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;<span class="name">div</span> <span class="attr">className</span>=<span class="string">&quot;list-group&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">            &#123;/* 原生html中，靠<span class="tag">&lt;<span class="name">a</span>&gt;</span>跳转不同的页面 */&#125;</span></span><br><span class="line"><span class="language-xml">            &#123;/* <span class="tag">&lt;<span class="name">a</span> <span class="attr">className</span>=<span class="string">&quot;list-group-item&quot;</span> <span class="attr">href</span>=<span class="string">&quot;./about.html&quot;</span>&gt;</span>About<span class="tag">&lt;/<span class="name">a</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">            <span class="tag">&lt;<span class="name">a</span> <span class="attr">className</span>=<span class="string">&quot;list-group-item active&quot;</span> <span class="attr">href</span>=<span class="string">&quot;./home.html&quot;</span>&gt;</span>Home<span class="tag">&lt;/<span class="name">a</span>&gt;</span> */&#125;</span></span><br><span class="line"><span class="language-xml"></span></span><br><span class="line"><span class="language-xml">            &#123;/* 在React中靠路由链接实现切换组件--编写路由链接 */&#125;</span></span><br><span class="line"><span class="language-xml">            <span class="tag">&lt;<span class="name">Link</span> <span class="attr">className</span>=<span class="string">&quot;list-group-item&quot;</span> <span class="attr">to</span>=<span class="string">&quot;/about&quot;</span>&gt;</span>About<span class="tag">&lt;/<span class="name">Link</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">            <span class="tag">&lt;<span class="name">Link</span> <span class="attr">className</span>=<span class="string">&quot;list-group-item&quot;</span> <span class="attr">to</span>=<span class="string">&quot;/home&quot;</span>&gt;</span>Home<span class="tag">&lt;/<span class="name">Link</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">div</span> <span class="attr">className</span>=<span class="string">&quot;col-xs-6&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;<span class="name">div</span> <span class="attr">className</span>=<span class="string">&quot;panel&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">              <span class="tag">&lt;<span class="name">div</span> <span class="attr">className</span>=<span class="string">&quot;panel-body&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">                &#123;/* 注册路由 */&#125;</span></span><br><span class="line"><span class="language-xml">                <span class="tag">&lt;<span class="name">Route</span> <span class="attr">path</span>=<span class="string">&#x27;/about&#x27;</span> <span class="attr">component</span>=<span class="string">&#123;About&#125;</span> /&gt;</span></span></span><br><span class="line"><span class="language-xml">                <span class="tag">&lt;<span class="name">Route</span> <span class="attr">path</span>=<span class="string">&#x27;/home&#x27;</span> <span class="attr">component</span>=<span class="string">&#123;Home&#125;</span> /&gt;</span></span></span><br><span class="line"><span class="language-xml">            <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">    <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">    )</span></span><br><span class="line"><span class="language-xml">  &#125;</span></span><br><span class="line"><span class="language-xml">&#125;</span></span><br></pre></td></tr></table></figure>
<h2 id="路由组件与一般组件的区别"><a href="#路由组件与一般组件的区别" class="headerlink" title="路由组件与一般组件的区别"></a>路由组件与一般组件的区别</h2><ul>
<li><p><strong>写法不同：</strong><br>  一般组件：<Demo/><br>  路由组件：<Route path="/demo" component={Demo}/></p>
</li>
<li><p><strong>存放位置不同：</strong><br>  一般组件：components</p>
<p>  路由组件：pages</p>
</li>
<li><p><strong>接收到的props不同：</strong><br>   一般组件：写组件标签时传递了什么，就能收到什么</p>
<p>   路由组件：接收到三个固定的属性</p>
</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">    <span class="attr">history</span>:</span><br><span class="line"><span class="attr">go</span>: ƒ <span class="title function_">go</span>(n)</span><br><span class="line"><span class="attr">goBack</span>: ƒ <span class="title function_">goBack</span>()</span><br><span class="line"><span class="attr">goForward</span>: ƒ <span class="title function_">goForward</span>()</span><br><span class="line"><span class="attr">push</span>: ƒ <span class="title function_">push</span>(path, state)</span><br><span class="line"><span class="attr">replace</span>: ƒ <span class="title function_">replace</span>(path, state)</span><br><span class="line">    <span class="attr">location</span>:</span><br><span class="line">        <span class="attr">pathname</span>: <span class="string">&quot;/about&quot;</span></span><br><span class="line">        <span class="attr">search</span>: <span class="string">&quot;&quot;</span></span><br><span class="line">        <span class="attr">state</span>: <span class="literal">undefined</span></span><br><span class="line">    <span class="attr">match</span>:</span><br><span class="line">        <span class="attr">params</span>: &#123;&#125;</span><br><span class="line">        <span class="attr">path</span>: <span class="string">&quot;/about&quot;</span></span><br><span class="line">        <span class="attr">url</span>: <span class="string">&quot;/about&quot;</span></span><br></pre></td></tr></table></figure>
<p>NavLink与封装NavLink<br>NavLink可以实现路由链接的高亮，通过activeClassName属性指定样式名，默认是”active”</p>
<p><code>&lt;NavLink activeClassName=&quot;demo&quot; className=&quot;list-group-item&quot; to=&quot;/home&quot;&gt;Home&lt;/NavLink&gt;</code><br>可以自己封装一个NavLink【一般组件】</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> <span class="title class_">React</span>, &#123; <span class="title class_">Component</span> &#125; <span class="keyword">from</span> <span class="string">&#x27;react&#x27;</span></span><br><span class="line"><span class="keyword">import</span> &#123;<span class="title class_">NavLink</span>&#125; <span class="keyword">from</span> <span class="string">&#x27;react-router-dom&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="keyword">class</span> <span class="title class_">MyNavLink</span> <span class="keyword">extends</span> <span class="title class_ inherited__">Component</span> &#123;</span><br><span class="line">  <span class="title function_">render</span>(<span class="params"></span>) &#123;</span><br><span class="line">	<span class="comment">// console.log(this.props);</span></span><br><span class="line">	<span class="keyword">return</span> (</span><br><span class="line">	  <span class="language-xml"><span class="tag">&lt;<span class="name">NavLik</span> <span class="attr">activeClassName</span>=<span class="string">&quot;demo&quot;</span> <span class="attr">className</span>=<span class="string">&quot;list-group-item&quot;</span> &#123;<span class="attr">...this.props</span>&#125; /&gt;</span></span></span><br><span class="line">	)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>标签体内容是特殊的标签属性通过this.props.children可以获取标签体内容<br>使用<br>    <code> &lt;MyNavLink to=&quot;/about&quot;&gt;About&lt;/MyNavLink&gt; &lt;MyNavLink to=&quot;/home&quot;&gt;Home&lt;/MyNavLink&gt;</code></p>
<h2 id="Switch的使用"><a href="#Switch的使用" class="headerlink" title="Switch的使用"></a>Switch的使用</h2><ol>
<li>通常情况下，path和component是一一对应的关系。</li>
<li>Switch可以提高路由匹配效率(单一匹配)。<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">&lt;<span class="title class_">Switch</span>&gt;</span><br><span class="line">  <span class="language-xml"><span class="tag">&lt;<span class="name">Route</span> <span class="attr">path</span>=<span class="string">&quot;/about&quot;</span> <span class="attr">component</span>=<span class="string">&#123;About&#125;/</span>&gt;</span></span></span><br><span class="line">  <span class="language-xml"><span class="tag">&lt;<span class="name">Route</span> <span class="attr">path</span>=<span class="string">&quot;/home&quot;</span> <span class="attr">component</span>=<span class="string">&#123;Home&#125;/</span>&gt;</span></span></span><br><span class="line">  <span class="language-xml"><span class="tag">&lt;<span class="name">Route</span> <span class="attr">path</span>=<span class="string">&quot;/home&quot;</span> <span class="attr">component</span>=<span class="string">&#123;Test&#125;/</span>&gt;</span></span></span><br><span class="line">&lt;/<span class="title class_">Switch</span>&gt;</span><br></pre></td></tr></table></figure>
这样只要匹配到了第一个就不会再往下匹配了</li>
</ol>
<h2 id="解决多级路径刷新页面样式丢失的问题"><a href="#解决多级路径刷新页面样式丢失的问题" class="headerlink" title="解决多级路径刷新页面样式丢失的问题"></a>解决多级路径刷新页面样式丢失的问题</h2><ol>
<li>public&#x2F;index.html 中 引入样式时不写 <code>./</code> 写 <code>/</code> （常用）【绝对路径】</li>
<li>public&#x2F;index.html 中 引入样式时不写 <code>./</code> 写 <code>%PUBLIC_URL%</code> （常用）</li>
<li>使用<code>HashRouter</code></li>
</ol>
<h2 id="路由的严格匹配与模糊匹配"><a href="#路由的严格匹配与模糊匹配" class="headerlink" title="路由的严格匹配与模糊匹配"></a>路由的严格匹配与模糊匹配</h2><ol>
<li>默认使用的是模糊匹配（简单记：【输入的路径】必须包含要【匹配的路径】，且顺序要一致）</li>
<li>开启严格匹配：<code>&lt;Route exact=&#123;true&#125; path=&quot;/about&quot; component=&#123;About&#125;/&gt;</code></li>
<li>严格匹配不要随便开启，需要再开，有些时候开启会导致无法继续匹配二级路由</li>
</ol>
<h2 id="Redirect的使用-【重定向】"><a href="#Redirect的使用-【重定向】" class="headerlink" title="Redirect的使用 【重定向】"></a>Redirect的使用 【重定向】</h2><ol>
<li>一般写在所有路由注册的最下方，当所有路由都无法匹配时，跳转到Redirect指定的路由</li>
<li>具体编码：<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">&lt;<span class="title class_">Switch</span>&gt;</span><br><span class="line">	<span class="language-xml"><span class="tag">&lt;<span class="name">Route</span> <span class="attr">path</span>=<span class="string">&quot;/about&quot;</span> <span class="attr">component</span>=<span class="string">&#123;About&#125;/</span>&gt;</span></span></span><br><span class="line">	<span class="language-xml"><span class="tag">&lt;<span class="name">Route</span> <span class="attr">path</span>=<span class="string">&quot;/home&quot;</span> <span class="attr">component</span>=<span class="string">&#123;Home&#125;/</span>&gt;</span></span></span><br><span class="line">	<span class="language-xml"><span class="tag">&lt;<span class="name">Redirect</span> <span class="attr">to</span>=<span class="string">&quot;/about&quot;</span>/&gt;</span></span></span><br><span class="line">&lt;/<span class="title class_">Switch</span>&gt;</span><br></pre></td></tr></table></figure></li>
</ol>
<h1 id="嵌套路由使用"><a href="#嵌套路由使用" class="headerlink" title="嵌套路由使用"></a>嵌套路由使用</h1><h2 id="效果-1"><a href="#效果-1" class="headerlink" title="效果"></a>效果</h2><p><img src="https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a1f30d888aad49e6bac704bac02a1acf~tplv-k3u1fbpfcp-watermark.image" alt="20210614220947211.gif"></p>
<h2 id="注意-1"><a href="#注意-1" class="headerlink" title="注意"></a>注意</h2><ol>
<li>注册子路由时要写上父路由的path值</li>
<li>路由的匹配是按照注册路由的顺序进行的</li>
</ol>
<h2 id="实现-1"><a href="#实现-1" class="headerlink" title="实现"></a>实现</h2><h3 id="Home-x2F-index-jsx"><a href="#Home-x2F-index-jsx" class="headerlink" title="Home&#x2F;index.jsx"></a>Home&#x2F;index.jsx</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> <span class="title class_">React</span>, &#123; <span class="title class_">Component</span> &#125; <span class="keyword">from</span> <span class="string">&#x27;react&#x27;</span></span><br><span class="line"><span class="keyword">import</span> &#123; <span class="title class_">Route</span>, <span class="title class_">NavLink</span>,<span class="title class_">Redirect</span>,<span class="title class_">Switch</span> &#125; <span class="keyword">from</span> <span class="string">&#x27;react-router-dom&#x27;</span></span><br><span class="line"><span class="keyword">import</span> <span class="title class_">News</span> <span class="keyword">from</span> <span class="string">&#x27;./News&#x27;</span></span><br><span class="line"><span class="keyword">import</span> <span class="title class_">Message</span> <span class="keyword">from</span> <span class="string">&#x27;./Message&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="keyword">class</span> <span class="title class_">Home</span> <span class="keyword">extends</span> <span class="title class_ inherited__">Component</span> &#123;</span><br><span class="line">  <span class="title function_">render</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> (</span><br><span class="line">      <span class="language-xml"><span class="tag">&lt;<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">h3</span>&gt;</span>我是Home的内容<span class="tag">&lt;/<span class="name">h3</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;<span class="name">ul</span> <span class="attr">className</span>=<span class="string">&quot;nav nav-tabs&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">            <span class="tag">&lt;<span class="name">li</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">              <span class="tag">&lt;<span class="name">NavLink</span> <span class="attr">className</span>=<span class="string">&quot;list-group-item&quot;</span> <span class="attr">to</span>=<span class="string">&quot;/home/news&quot;</span>&gt;</span>News<span class="tag">&lt;/<span class="name">NavLink</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">            <span class="tag">&lt;/<span class="name">li</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">            <span class="tag">&lt;<span class="name">li</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">              <span class="tag">&lt;<span class="name">NavLink</span> <span class="attr">className</span>=<span class="string">&quot;list-group-item&quot;</span> <span class="attr">to</span>=<span class="string">&quot;/home/message&quot;</span>&gt;</span>Message<span class="tag">&lt;/<span class="name">NavLink</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">            <span class="tag">&lt;/<span class="name">li</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;/<span class="name">ul</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;<span class="name">Switch</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">            <span class="tag">&lt;<span class="name">Route</span> <span class="attr">path</span>=<span class="string">&#x27;/home/news&#x27;</span> <span class="attr">component</span>=<span class="string">&#123;News&#125;</span> /&gt;</span></span></span><br><span class="line"><span class="language-xml">            <span class="tag">&lt;<span class="name">Route</span> <span class="attr">path</span>=<span class="string">&#x27;/home/message&#x27;</span> <span class="attr">component</span>=<span class="string">&#123;Message&#125;</span> /&gt;</span></span></span><br><span class="line"><span class="language-xml">            <span class="tag">&lt;<span class="name">Redirect</span> <span class="attr">to</span>=<span class="string">&#x27;/home/news&#x27;</span> /&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;/<span class="name">Switch</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line">    )</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h1 id="向路由组件传递参数数据"><a href="#向路由组件传递参数数据" class="headerlink" title="向路由组件传递参数数据"></a>向路由组件传递参数数据</h1><h2 id="效果-2"><a href="#效果-2" class="headerlink" title="效果"></a>效果</h2><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/8ad73391ce2542799a57836e3a868c8c~tplv-k3u1fbpfcp-watermark.image" alt="20210614225203116.gif"></p>
<h2 id="具体方法"><a href="#具体方法" class="headerlink" title="具体方法"></a>具体方法</h2><p>方法1. params参数<br>路由链接(携带参数)：<code>&lt;Link to=&#39;/demo/test/tom/18&#39;&#125;&gt;详情&lt;/Link&gt;</code><br>注册路由(声明接收)：<code>&lt;Route path=&quot;/demo/test/:name/:age&quot; component=&#123;Test&#125;/&gt;</code><br>接收参数：<code>&lt;Route path=&quot;/demo/test/:name/:age&quot; component=&#123;Test&#125;/&gt;</code></p>
<h4 id="Message-x2F-index-jsx"><a href="#Message-x2F-index-jsx" class="headerlink" title="Message&#x2F;index.jsx"></a>Message&#x2F;index.jsx</h4><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> <span class="title class_">React</span>, &#123; <span class="title class_">Component</span> &#125; <span class="keyword">from</span> <span class="string">&#x27;react&#x27;</span></span><br><span class="line"><span class="keyword">import</span> &#123; <span class="title class_">Link</span>, <span class="title class_">Route</span> &#125; <span class="keyword">from</span> <span class="string">&#x27;react-router-dom&#x27;</span>;</span><br><span class="line"><span class="keyword">import</span> <span class="title class_">Detail</span> <span class="keyword">from</span> <span class="string">&#x27;./Detail&#x27;</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="keyword">class</span> <span class="title class_">Message</span> <span class="keyword">extends</span> <span class="title class_ inherited__">Component</span> &#123;</span><br><span class="line">  state = &#123;</span><br><span class="line">    <span class="attr">messageArr</span>: [</span><br><span class="line">      &#123; <span class="attr">id</span>: <span class="string">&#x27;01&#x27;</span>, <span class="attr">title</span>: <span class="string">&#x27;消息1&#x27;</span> &#125;,</span><br><span class="line">      &#123; <span class="attr">id</span>: <span class="string">&#x27;02&#x27;</span>, <span class="attr">title</span>: <span class="string">&#x27;消息2&#x27;</span> &#125;,</span><br><span class="line">      &#123; <span class="attr">id</span>: <span class="string">&#x27;03&#x27;</span>, <span class="attr">title</span>: <span class="string">&#x27;消息3&#x27;</span> &#125;,</span><br><span class="line">    ]</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="title function_">render</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">const</span> &#123; messageArr &#125; = <span class="variable language_">this</span>.<span class="property">state</span>;</span><br><span class="line">    <span class="keyword">return</span> (</span><br><span class="line">      <span class="language-xml"><span class="tag">&lt;<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">ul</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          &#123;</span></span><br><span class="line"><span class="language-xml">            messageArr.map((msgObj) =&gt; &#123;</span></span><br><span class="line"><span class="language-xml">              return (</span></span><br><span class="line"><span class="language-xml">                <span class="tag">&lt;<span class="name">li</span> <span class="attr">key</span>=<span class="string">&#123;msgObj.id&#125;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">                  &#123;/* 向路由组件传递params参数 */&#125;</span></span><br><span class="line"><span class="language-xml">                  <span class="tag">&lt;<span class="name">Link</span> <span class="attr">to</span>=<span class="string">&#123;</span>`/<span class="attr">home</span>/<span class="attr">message</span>/<span class="attr">detail</span>/$&#123;<span class="attr">msgObj.id</span>&#125;/$&#123;<span class="attr">msgObj.title</span>&#125;`&#125;&gt;</span>&#123;msgObj.title&#125;<span class="tag">&lt;/<span class="name">Link</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">                <span class="tag">&lt;/<span class="name">li</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">              )</span></span><br><span class="line"><span class="language-xml">            &#125;)</span></span><br><span class="line"><span class="language-xml">          &#125;</span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;/<span class="name">ul</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">hr</span> /&gt;</span></span></span><br><span class="line"><span class="language-xml">        &#123;/* 声明接收params参数 */&#125;</span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">Route</span> <span class="attr">path</span>=<span class="string">&quot;/home/message/detail/:id/:title&quot;</span> <span class="attr">component</span>=<span class="string">&#123;Detail&#125;/</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line">    )</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h4 id="Detail-x2F-index-jsx"><a href="#Detail-x2F-index-jsx" class="headerlink" title="Detail&#x2F;index.jsx"></a>Detail&#x2F;index.jsx</h4><p><img src="https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/b7b56e39ce3f4518a173b4201b8297a4~tplv-k3u1fbpfcp-watermark.image" alt="20210614224952124.png"></p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> <span class="title class_">React</span>, &#123; <span class="title class_">Component</span> &#125; <span class="keyword">from</span> <span class="string">&#x27;react&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="keyword">class</span> <span class="title class_">Detail</span> <span class="keyword">extends</span> <span class="title class_ inherited__">Component</span> &#123;</span><br><span class="line">  state = &#123;</span><br><span class="line">    detailData : [</span><br><span class="line">      &#123; <span class="attr">id</span>: <span class="string">&#x27;01&#x27;</span>, <span class="attr">content</span>: <span class="string">&#x27;你好啊&#x27;</span> &#125;,</span><br><span class="line">      &#123; <span class="attr">id</span>: <span class="string">&#x27;02&#x27;</span>, <span class="attr">content</span>: <span class="string">&#x27;还不错鸭&#x27;</span> &#125;,</span><br><span class="line">      &#123; <span class="attr">id</span>: <span class="string">&#x27;03&#x27;</span>, <span class="attr">content</span>: <span class="string">&#x27;显示我吧&#x27;</span> &#125;</span><br><span class="line">    ]</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="title function_">render</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>.<span class="property">props</span>)</span><br><span class="line">    <span class="comment">// 接收params参数</span></span><br><span class="line">    <span class="keyword">const</span> &#123; id, title &#125; = <span class="variable language_">this</span>.<span class="property">props</span>.<span class="property">match</span>.<span class="property">params</span></span><br><span class="line">    <span class="keyword">const</span> findResult= <span class="variable language_">this</span>.<span class="property">state</span>.<span class="property">detailData</span>.<span class="title function_">find</span>(<span class="function">(<span class="params">dataObj</span>) =&gt;</span> &#123;</span><br><span class="line">      <span class="keyword">return</span> dataObj.<span class="property">id</span> === id</span><br><span class="line">    &#125;)</span><br><span class="line">    <span class="keyword">return</span> (</span><br><span class="line">      <span class="language-xml"><span class="tag">&lt;<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">ul</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;<span class="name">li</span>&gt;</span>ID: &#123;id &#125;<span class="tag">&lt;/<span class="name">li</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;<span class="name">li</span>&gt;</span>Title: &#123;title &#125;<span class="tag">&lt;/<span class="name">li</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;<span class="name">li</span>&gt;</span>Content: &#123; findResult.content&#125;<span class="tag">&lt;/<span class="name">li</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;/<span class="name">ul</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line">    )</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>方法2. search参数<br>路由链接(携带参数)：<code>&lt;Link to=&#39;/demo/test?name=tom&amp;age=18&#39;&#125;&gt;详情&lt;/Link&gt;</code><br>注册路由(无需声明，正常注册即可)：<code>&lt;Route path=&quot;/demo/test&quot; component=&#123;Test&#125;/&gt;</code><br>接收参数：<code>this.props.location.search</code><br>备注：获取到的search是urlencoded编码字符串，需要借助querystring解析</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> qs <span class="keyword">from</span> <span class="string">&#x27;querystring&#x27;</span></span><br><span class="line"><span class="keyword">let</span> obj = &#123;<span class="attr">name</span>:<span class="string">&#x27;tom&#x27;</span>, <span class="attr">age</span>:<span class="number">18</span>&#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(qs.<span class="title function_">stringify</span>(obj)) <span class="comment">// name=tom&amp;age=18</span></span><br><span class="line"><span class="keyword">let</span> str = <span class="string">&#x27;carName=Benz&amp;price=199&#x27;</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(qs.<span class="title function_">parse</span>(str)) <span class="comment">// &#123;carName: &#x27;Benz&#x27;, price: 199&#125;</span></span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>方法3. state参数<br>路由链接(携带参数)：<code>&lt;Link to=&#123;&#123; pathname:'/demo/test', state:&#123;name:'tom',age:18&#125; &#125;&#125;&gt;详情&lt;/Link&gt;</code><br>注册路由(无需声明，正常注册即可)：<code>&lt;Route path=&quot;/demo/test&quot; component=&#123;Test&#125;/&gt;</code><br>接收参数：<code>this.props.location.state</code><br>备注：刷新也可以保留住参数【history对象记录着在】</p>
<h4 id="Message-x2F-index-jsx-1"><a href="#Message-x2F-index-jsx-1" class="headerlink" title="Message&#x2F;index.jsx"></a>Message&#x2F;index.jsx</h4><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="keyword">class</span> <span class="title class_">Message</span> <span class="keyword">extends</span> <span class="title class_ inherited__">Component</span> &#123;</span><br><span class="line">  <span class="title function_">render</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">const</span> &#123;messageArr&#125; = <span class="variable language_">this</span>.<span class="property">state</span></span><br><span class="line">    <span class="keyword">return</span> (</span><br><span class="line">      <span class="language-xml"><span class="tag">&lt;<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">ul</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          &#123;</span></span><br><span class="line"><span class="language-xml">            messageArr.map((msgObj)=&gt;&#123;</span></span><br><span class="line"><span class="language-xml">              return (</span></span><br><span class="line"><span class="language-xml">                <span class="tag">&lt;<span class="name">li</span> <span class="attr">key</span>=<span class="string">&#123;msgObj.id&#125;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml"></span></span><br><span class="line"><span class="language-xml">                  &#123;/* 向路由组件传递params参数 */&#125;</span></span><br><span class="line"><span class="language-xml">                  &#123;/* <span class="tag">&lt;<span class="name">Link</span> <span class="attr">to</span>=<span class="string">&#123;</span>`/<span class="attr">home</span>/<span class="attr">message</span>/<span class="attr">detail</span>/$&#123;<span class="attr">msgObj.id</span>&#125;/$&#123;<span class="attr">msgObj.title</span>&#125;`&#125;&gt;</span>&#123;msgObj.title&#125;<span class="tag">&lt;/<span class="name">Link</span>&gt;</span> */&#125;</span></span><br><span class="line"><span class="language-xml"></span></span><br><span class="line"><span class="language-xml">                  &#123;/* 向路由组件传递search参数 */&#125;</span></span><br><span class="line"><span class="language-xml">                  &#123;/* <span class="tag">&lt;<span class="name">Link</span> <span class="attr">to</span>=<span class="string">&#123;</span>`/<span class="attr">home</span>/<span class="attr">message</span>/<span class="attr">detail</span>/?<span class="attr">id</span>=<span class="string">$&#123;msgObj.id&#125;&amp;title</span>=<span class="string">$&#123;msgObj.title&#125;</span>`&#125;&gt;</span>&#123;msgObj.title&#125;<span class="tag">&lt;/<span class="name">Link</span>&gt;</span> */&#125;</span></span><br><span class="line"><span class="language-xml"></span></span><br><span class="line"><span class="language-xml">                  &#123;/* 向路由组件传递state参数 */&#125;</span></span><br><span class="line"><span class="language-xml">                  <span class="tag">&lt;<span class="name">Link</span> <span class="attr">to</span>=<span class="string">&#123;&#123;pathname:</span>&#x27;/<span class="attr">home</span>/<span class="attr">message</span>/<span class="attr">detail</span>&#x27;,<span class="attr">state:</span>&#123;<span class="attr">id:msgObj.id</span>,<span class="attr">title:msgObj.title</span>&#125;&#125;&#125;&gt;</span>&#123;msgObj.title&#125;<span class="tag">&lt;/<span class="name">Link</span>&gt;</span></span></span><br><span class="line"><span class="language-xml"></span></span><br><span class="line"><span class="language-xml">                <span class="tag">&lt;/<span class="name">li</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">              )</span></span><br><span class="line"><span class="language-xml">            &#125;)</span></span><br><span class="line"><span class="language-xml">          &#125;</span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;/<span class="name">ul</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">hr</span>/&gt;</span></span></span><br><span class="line"><span class="language-xml">        &#123;/* 声明接收params参数 */&#125;</span></span><br><span class="line"><span class="language-xml">        &#123;/* <span class="tag">&lt;<span class="name">Route</span> <span class="attr">path</span>=<span class="string">&quot;/home/message/detail/:id/:title&quot;</span> <span class="attr">component</span>=<span class="string">&#123;Detail&#125;/</span>&gt;</span> */&#125;</span></span><br><span class="line"><span class="language-xml"></span></span><br><span class="line"><span class="language-xml">        &#123;/* search参数无需声明接收，正常注册路由即可 */&#125;</span></span><br><span class="line"><span class="language-xml">        &#123;/* <span class="tag">&lt;<span class="name">Route</span> <span class="attr">path</span>=<span class="string">&quot;/home/message/detail&quot;</span> <span class="attr">component</span>=<span class="string">&#123;Detail&#125;/</span>&gt;</span> */&#125;</span></span><br><span class="line"><span class="language-xml"></span></span><br><span class="line"><span class="language-xml">        &#123;/* state参数无需声明接收，正常注册路由即可 */&#125;</span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">Route</span> <span class="attr">path</span>=<span class="string">&quot;/home/message/detail&quot;</span> <span class="attr">component</span>=<span class="string">&#123;Detail&#125;/</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line">    )</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h4 id="Detail-x2F-index-jsx-1"><a href="#Detail-x2F-index-jsx-1" class="headerlink" title="Detail&#x2F;index.jsx"></a>Detail&#x2F;index.jsx</h4><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> <span class="title class_">React</span>, &#123; <span class="title class_">Component</span> &#125; <span class="keyword">from</span> <span class="string">&#x27;react&#x27;</span></span><br><span class="line"><span class="comment">// import qs from &#x27;querystring&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="keyword">class</span> <span class="title class_">Detail</span> <span class="keyword">extends</span> <span class="title class_ inherited__">Component</span> &#123;</span><br><span class="line">  <span class="title function_">render</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>.<span class="property">props</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 接收params参数</span></span><br><span class="line">    <span class="comment">// const &#123;id,title&#125; = this.props.match.params </span></span><br><span class="line"></span><br><span class="line">    <span class="comment">// 接收search参数</span></span><br><span class="line">    <span class="comment">// const &#123;search&#125; = this.props.location</span></span><br><span class="line">    <span class="comment">// const &#123;id,title&#125; = qs.parse(search.slice(1))</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">// 接收state参数</span></span><br><span class="line">    <span class="keyword">const</span> &#123;id,title&#125; = <span class="variable language_">this</span>.<span class="property">props</span>.<span class="property">location</span>.<span class="property">state</span> || &#123;&#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">const</span> findResult = <span class="title class_">DetailData</span>.<span class="title function_">find</span>(<span class="function">(<span class="params">detailObj</span>)=&gt;</span>&#123;</span><br><span class="line">      <span class="keyword">return</span> detailObj.<span class="property">id</span> === id</span><br><span class="line">    &#125;) || &#123;&#125;</span><br><span class="line">    <span class="keyword">return</span> (</span><br><span class="line">      <span class="language-xml"><span class="tag">&lt;<span class="name">ul</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">li</span>&gt;</span>ID:&#123;id&#125;<span class="tag">&lt;/<span class="name">li</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">li</span>&gt;</span>TITLE:&#123;title&#125;<span class="tag">&lt;/<span class="name">li</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">li</span>&gt;</span>CONTENT:&#123;findResult.content&#125;<span class="tag">&lt;/<span class="name">li</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;/<span class="name">ul</span>&gt;</span></span></span><br><span class="line">    )</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="多种路由跳转方式"><a href="#多种路由跳转方式" class="headerlink" title="多种路由跳转方式"></a>多种路由跳转方式</h3><h4 id="编程式路由导航"><a href="#编程式路由导航" class="headerlink" title="编程式路由导航"></a>编程式路由导航</h4><p>借助this.prosp.history对象上的API对操作路由跳转、前进、后退</p>
<ul>
<li>this.prosp.history.push()</li>
<li>this.prosp.history.replace()</li>
<li>this.prosp.history.goBack()</li>
<li>this.prosp.history.goForward()</li>
<li>this.prosp.history.go()</li>
</ul>
<p> withRouter的使用<br> <code>export default withRouter(Header)</code><br> <code>withRouter</code>可以加工一般组件，让一般组件具备路由组件所特有的API<br><code>withRouter</code>的返回值是一个新组件</p>
<h1 id="注意-2"><a href="#注意-2" class="headerlink" title="注意"></a>注意</h1><h2 id="BrowserRouter与HashRouter的区别"><a href="#BrowserRouter与HashRouter的区别" class="headerlink" title="BrowserRouter与HashRouter的区别"></a>BrowserRouter与HashRouter的区别</h2><p>底层原理不一样：</p>
<ul>
<li>BrowserRouter使用的是H5的history API，不兼容IE9及以下版本。</li>
<li>HashRouter使用的是URL的哈希值。</li>
<li>path表现形式不一样</li>
<li>BrowserRouter的路径中没有#,例如：localhost:3000&#x2F;demo&#x2F;test</li>
<li>HashRouter的路径包含#,例如：localhost:3000&#x2F;#&#x2F;demo&#x2F;test</li>
<li>刷新后对路由state参数的影响<ol>
<li>BrowserRouter没有任何影响，因为state保存在history对象中 </li>
<li>HashRouter刷新后会导致路由state参数的丢失！！！</li>
</ol>
</li>
<li>备注：HashRouter可以用于解决一些路径错误相关的问题。</li>
<li><h1 id="redux理解"><a href="#redux理解" class="headerlink" title="redux理解"></a><a target="_blank" rel="noopener" href="https://so.csdn.net/so/search?from=pc_blog_highlight&q=redux">redux</a>理解</h1></li>
</ul>
<h2 id="相关文档"><a href="#相关文档" class="headerlink" title=" 相关文档"></a><a href=""></a><a href=""></a> 相关文档</h2><p>中文文档: <a target="_blank" rel="noopener" href="http://www.redux.org.cn/">http://www.redux.org.cn/</a></p>
<p>Github: <a target="_blank" rel="noopener" href="https://github.com/reactjs/redux">https://github.com/reactjs/redux</a><br>先把它装上<br><code>npm i redux</code></p>
<h2 id="redux是什么"><a href="#redux是什么" class="headerlink" title="redux是什么"></a>redux是什么</h2><ol>
<li>redux是一个专门用于做<code>状态管理</code>的JS库(不是react插件库)。</li>
<li>可以用在react, angular, vue等项目中, 但基本与react配合使用。</li>
<li>作用: 集中式管理react应用中多个组件<code>共享</code>的状态</li>
</ol>
<h2 id="什么情况下需要使用redux"><a href="#什么情况下需要使用redux" class="headerlink" title="什么情况下需要使用redux"></a>什么情况下需要使用redux</h2><ol>
<li>某个组件的状态，需要让其他组件可以随时拿到（共享）</li>
<li>一个组件需要改变另一个组件的状态（通信）</li>
<li>总体原则：能不用就不用, 如果不用比较吃力才考虑使用</li>
</ol>
<h2 id="redux工作流程"><a href="#redux工作流程" class="headerlink" title="redux工作流程"></a>redux工作流程</h2><p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d816d5cbefe24548a239065895bd2573~tplv-k3u1fbpfcp-watermark.image" alt="20210615225020695.png"></p>
<h1 id="redux的三个核心概念"><a href="#redux的三个核心概念" class="headerlink" title="redux的三个核心概念"></a>redux的三个核心概念</h1><h2 id="action"><a href="#action" class="headerlink" title="action"></a>action</h2><ol>
<li><p>动作的对象</p>
</li>
<li><p>包含 2 个属性</p>
<ul>
<li><code>type</code>：标识属性, 值为字符串, 唯一, 必要属性</li>
<li><code>data</code>：数据属性, 值类型任意, 可选属性</li>
</ul>
</li>
<li><p>例子：<code>&#123; type: &#39;ADD_STUDENT&#39;,data:&#123;name: &#39;tom&#39;,age:18&#125; &#125;</code></p>
</li>
</ol>
<h2 id="reducer"><a href="#reducer" class="headerlink" title="reducer"></a>reducer</h2><ol>
<li>用于初始化状态、加工状态。</li>
<li>加工时，根据旧的<code>state</code>和<code>action</code>， 产生新的<code>state</code>的纯函数。</li>
</ol>
<h2 id="store"><a href="#store" class="headerlink" title="store"></a>store</h2><p>将state、action、reducer联系在一起的对象</p>
<p>如何得到此对象?</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> &#123;createStore&#125; <span class="keyword">from</span> <span class="string">&#x27;redux&#x27;</span></span><br><span class="line"><span class="keyword">import</span> reducer <span class="keyword">from</span> <span class="string">&#x27;./reducers&#x27;</span></span><br><span class="line"><span class="keyword">const</span> store = <span class="title function_">createStore</span>(reducer)</span><br></pre></td></tr></table></figure>
<p>此对象的功能?</p>
<ul>
<li>getState(): 得到state</li>
<li>dispatch(action): 分发action, 触发reducer调用, 产生新的state</li>
<li>subscribe(listener): 注册监听, 当产生了新的state时, 自动调用</li>
</ul>
<h1 id="API"><a href="#API" class="headerlink" title="API"></a>API</h1><h4 id="createStore"><a href="#createStore" class="headerlink" title="createStore()"></a>createStore()</h4><p>作用：创建包含指定reducer的store对象</p>
<h4 id="store对象"><a href="#store对象" class="headerlink" title="store对象"></a>store对象</h4><p>作用: redux库最核心的管理对象<br>它内部维护着:</p>
<ul>
<li>state</li>
<li>reducer<br>核心方法:<br><code>getState()</code><br><code>dispatch(action)</code><br><code>subscribe(listener)</code><br>具体编码:<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">store.<span class="title function_">getState</span>()</span><br><span class="line">store.<span class="title function_">dispatch</span>(&#123;<span class="attr">type</span>:<span class="string">&#x27;INCREMENT&#x27;</span>, number&#125;)</span><br><span class="line">store.<span class="title function_">subscribe</span>(render)</span><br><span class="line"><span class="title function_">applyMiddleware</span>()</span><br></pre></td></tr></table></figure>
作用：应用上基于redux的中间件(插件库)</li>
</ul>
<h4 id="combineReducers"><a href="#combineReducers" class="headerlink" title="combineReducers()"></a>combineReducers()</h4><p>作用：合并多个reducer函数</p>
<h4 id="使用redux编写应用"><a href="#使用redux编写应用" class="headerlink" title="使用redux编写应用"></a>使用redux编写应用</h4><p>效果</p>
<p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/e4819bf7051747208e032e5641fbfae7~tplv-k3u1fbpfcp-watermark.image" alt="20210617232712887.gif"></p>
<h2 id="实现-2"><a href="#实现-2" class="headerlink" title="实现"></a>实现</h2><h3 id="redux-x2F-store-js"><a href="#redux-x2F-store-js" class="headerlink" title="redux&#x2F;store.js"></a><a href=""></a><a href=""></a>redux&#x2F;store.js</h3><blockquote>
<p>该文件专门用于暴露一个store对象，整个应用只有一个store对象</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">/ 引入createStore，专门用于创建redux中最为核心的store对象</span><br><span class="line"><span class="keyword">import</span> &#123; createStore &#125; <span class="keyword">from</span> <span class="string">&quot;redux&quot;</span>;</span><br><span class="line"><span class="comment">// 引入为Count组件服务的reducer</span></span><br><span class="line"><span class="keyword">import</span> countReducer <span class="keyword">from</span> <span class="string">&quot;./count_reducer.js&quot;</span>;</span><br><span class="line"><span class="comment">// 暴露store</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="title function_">createStore</span>(countReducer);</span><br></pre></td></tr></table></figure>
<h3 id="redux-x2F-count-reducer-js"><a href="#redux-x2F-count-reducer-js" class="headerlink" title="redux&#x2F;count_reducer.js"></a>redux&#x2F;count_reducer.js</h3><p>该文件是用于创建一个为Count组件服务的reducer，reducer的本质就是一个函数<br>reducer函数会接到两个参数，分别为：之前的状态(preState)，动作对象(action)</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> &#123;<span class="variable constant_">INCREMENT</span>,<span class="variable constant_">DECREMENT</span>&#125; <span class="keyword">from</span> <span class="string">&#x27;./constant&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> initState = <span class="number">0</span> <span class="comment">//初始化状态</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="keyword">function</span> <span class="title function_">countReducer</span>(<span class="params">preState=initState,action</span>)&#123;</span><br><span class="line">  <span class="comment">// console.log(preState);</span></span><br><span class="line">  <span class="comment">//从action对象中获取：type、data</span></span><br><span class="line">  <span class="keyword">const</span> &#123;type,data&#125; = action</span><br><span class="line">  <span class="comment">//根据type决定如何加工数据</span></span><br><span class="line">  <span class="keyword">switch</span> (type) &#123;</span><br><span class="line">    <span class="keyword">case</span> <span class="attr">INCREMENT</span>: <span class="comment">//如果是加</span></span><br><span class="line">      <span class="keyword">return</span> preState + data</span><br><span class="line">    <span class="keyword">case</span> <span class="attr">DECREMENT</span>: <span class="comment">//若果是减</span></span><br><span class="line">      <span class="keyword">return</span> preState - data</span><br><span class="line">    <span class="attr">default</span>:</span><br><span class="line">      <span class="keyword">return</span> preState</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="redux-x2F-count-action-js"><a href="#redux-x2F-count-action-js" class="headerlink" title="redux&#x2F;count_action.js"></a>redux&#x2F;count_action.js</h3><p>该文件专门为Count组件生成action对象</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> &#123;<span class="variable constant_">INCREMENT</span>,<span class="variable constant_">DECREMENT</span>&#125; <span class="keyword">from</span> <span class="string">&#x27;./constant&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">const</span> <span class="title function_">createIncrementAction</span> = data =&gt; (&#123;<span class="attr">type</span>:<span class="variable constant_">INCREMENT</span>,data&#125;)</span><br><span class="line"><span class="keyword">export</span> <span class="keyword">const</span> <span class="title function_">createDecrementAction</span> = data =&gt; (&#123;<span class="attr">type</span>:<span class="variable constant_">DECREMENT</span>,data&#125;)</span><br></pre></td></tr></table></figure>
<h3 id="redux-x2F-constant-js"><a href="#redux-x2F-constant-js" class="headerlink" title="redux&#x2F;constant.js"></a>redux&#x2F;constant.js</h3><blockquote>
<p>该模块是用于定义action对象中type类型的常量值，目的只有一个：便于管理的同时防止程序员单词写错<br><code>export const INCREMENT = &#39;increment&#39; export const DECREMENT = &#39;decrement&#39;</code></p>
</blockquote>
<h3 id="Count-x2F-index-jsx"><a href="#Count-x2F-index-jsx" class="headerlink" title="Count&#x2F;index.jsx"></a>Count&#x2F;index.jsx</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> <span class="title class_">React</span>, &#123; <span class="title class_">Component</span> &#125; <span class="keyword">from</span> <span class="string">&#x27;react&#x27;</span></span><br><span class="line"><span class="comment">//引入store，用于获取redux中保存状态</span></span><br><span class="line"><span class="keyword">import</span> store <span class="keyword">from</span> <span class="string">&#x27;../../redux/store&#x27;</span></span><br><span class="line"><span class="comment">//引入actionCreator，专门用于创建action对象</span></span><br><span class="line"><span class="keyword">import</span> &#123;createIncrementAction,createDecrementAction&#125; <span class="keyword">from</span> <span class="string">&#x27;../../redux/count_action&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="keyword">class</span> <span class="title class_">Count</span> <span class="keyword">extends</span> <span class="title class_ inherited__">Component</span> &#123;</span><br><span class="line"></span><br><span class="line">  <span class="comment">/* componentDidMount()&#123;</span></span><br><span class="line"><span class="comment">    //检测redux中状态的变化，只要变化，就调用render</span></span><br><span class="line"><span class="comment">    store.subscribe(()=&gt;&#123;</span></span><br><span class="line"><span class="comment">      this.setState(&#123;&#125;)</span></span><br><span class="line"><span class="comment">    &#125;)</span></span><br><span class="line"><span class="comment">  &#125; */</span></span><br><span class="line"></span><br><span class="line">  <span class="comment">//加法</span></span><br><span class="line">  increment = <span class="function">()=&gt;</span>&#123;</span><br><span class="line">    <span class="keyword">const</span> &#123;value&#125; = <span class="variable language_">this</span>.<span class="property">selectNumber</span></span><br><span class="line">    store.<span class="title function_">dispatch</span>(<span class="title function_">createIncrementAction</span>(value*<span class="number">1</span>))</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">//减法</span></span><br><span class="line">  decrement = <span class="function">()=&gt;</span>&#123;</span><br><span class="line">    <span class="keyword">const</span> &#123;value&#125; = <span class="variable language_">this</span>.<span class="property">selectNumber</span></span><br><span class="line">    store.<span class="title function_">dispatch</span>(<span class="title function_">createDecrementAction</span>(value*<span class="number">1</span>))</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">//奇数再加</span></span><br><span class="line">  incrementIfOdd = <span class="function">()=&gt;</span>&#123;</span><br><span class="line">    <span class="keyword">const</span> &#123;value&#125; = <span class="variable language_">this</span>.<span class="property">selectNumber</span></span><br><span class="line">    <span class="keyword">const</span> count = store.<span class="title function_">getState</span>()</span><br><span class="line">    <span class="keyword">if</span>(count % <span class="number">2</span> !== <span class="number">0</span>)&#123;</span><br><span class="line">      store.<span class="title function_">dispatch</span>(<span class="title function_">createIncrementAction</span>(value*<span class="number">1</span>))</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">//异步加</span></span><br><span class="line">  incrementAsync = <span class="function">()=&gt;</span>&#123;</span><br><span class="line">    <span class="keyword">const</span> &#123;value&#125; = <span class="variable language_">this</span>.<span class="property">selectNumber</span></span><br><span class="line">    <span class="built_in">setTimeout</span>(<span class="function">()=&gt;</span>&#123;</span><br><span class="line">      store.<span class="title function_">dispatch</span>(<span class="title function_">createIncrementAction</span>(value*<span class="number">1</span>))</span><br><span class="line">    &#125;,<span class="number">500</span>)</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="title function_">render</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> (</span><br><span class="line">      <span class="language-xml"><span class="tag">&lt;<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">h1</span>&gt;</span>当前求和为：&#123;store.getState()&#125;<span class="tag">&lt;/<span class="name">h1</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">select</span> <span class="attr">ref</span>=<span class="string">&#123;c</span> =&gt;</span> this.selectNumber = c&#125;&gt;</span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;<span class="name">option</span> <span class="attr">value</span>=<span class="string">&quot;1&quot;</span>&gt;</span>1<span class="tag">&lt;/<span class="name">option</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;<span class="name">option</span> <span class="attr">value</span>=<span class="string">&quot;2&quot;</span>&gt;</span>2<span class="tag">&lt;/<span class="name">option</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;<span class="name">option</span> <span class="attr">value</span>=<span class="string">&quot;3&quot;</span>&gt;</span>3<span class="tag">&lt;/<span class="name">option</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;/<span class="name">select</span>&gt;</span><span class="symbol">&amp;nbsp;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">button</span> <span class="attr">onClick</span>=<span class="string">&#123;this.increment&#125;</span>&gt;</span>+<span class="tag">&lt;/<span class="name">button</span>&gt;</span><span class="symbol">&amp;nbsp;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">button</span> <span class="attr">onClick</span>=<span class="string">&#123;this.decrement&#125;</span>&gt;</span>-<span class="tag">&lt;/<span class="name">button</span>&gt;</span><span class="symbol">&amp;nbsp;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">button</span> <span class="attr">onClick</span>=<span class="string">&#123;this.incrementIfOdd&#125;</span>&gt;</span>当前求和为奇数再加<span class="tag">&lt;/<span class="name">button</span>&gt;</span><span class="symbol">&amp;nbsp;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">button</span> <span class="attr">onClick</span>=<span class="string">&#123;this.incrementAsync&#125;</span>&gt;</span>异步加<span class="tag">&lt;/<span class="name">button</span>&gt;</span><span class="symbol">&amp;nbsp;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line">    )</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="index-js-1"><a href="#index-js-1" class="headerlink" title="index.js"></a>index.js</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> <span class="title class_">React</span> <span class="keyword">from</span> <span class="string">&#x27;react&#x27;</span></span><br><span class="line"><span class="keyword">import</span> <span class="title class_">ReactDOM</span> <span class="keyword">from</span> <span class="string">&#x27;react-dom&#x27;</span></span><br><span class="line"><span class="keyword">import</span> <span class="title class_">App</span> <span class="keyword">from</span> <span class="string">&#x27;./App&#x27;</span></span><br><span class="line"><span class="keyword">import</span> store <span class="keyword">from</span> <span class="string">&#x27;./redux/store&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="title class_">ReactDOM</span>.<span class="title function_">render</span>(<span class="language-xml"><span class="tag">&lt;<span class="name">App</span>/&gt;</span></span>,<span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;root&#x27;</span>))</span><br><span class="line"></span><br><span class="line"><span class="comment">// 监测redux中状态的改变，如redux的状态发生了改变，那么重新渲染App组件</span></span><br><span class="line">store.<span class="title function_">subscribe</span>(<span class="function">()=&gt;</span>&#123;</span><br><span class="line">	<span class="title class_">ReactDOM</span>.<span class="title function_">render</span>(<span class="language-xml"><span class="tag">&lt;<span class="name">App</span>/&gt;</span></span>,<span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;root&#x27;</span>))</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<p>总结</p>
<h3 id="store-js："><a href="#store-js：" class="headerlink" title="store.js："></a>store.js：</h3><p>1). 引入redux中的createStore函数，创建一个store<br>2). createStore调用时要传入一个为其服务的reducer<br>3). 记得暴露store对象</p>
<h4 id="count-reducer-js："><a href="#count-reducer-js：" class="headerlink" title="count_reducer.js："></a>count_reducer.js：</h4><ul>
<li>reducer的本质是一个函数，接收：preState,action，返回加工后的状态</li>
<li>reducer有两个作用：初始化状态，加工状态</li>
<li>reducer被第一次调用时，是store自动触发的，</li>
<li>传递的preState是undefined,</li>
<li>传递的action是:{type:‘@@REDUX&#x2F;INIT_a.2.b.4}</li>
<li>在index.js中监测store中状态的改变，一旦发生改变重新渲染<App/></li>
<li>备注：redux只负责管理状态，至于状态的改变驱动着页面的展示，要靠我们自己写。</li>
</ul>
<p>完整版新增文件：</p>
<ul>
<li>count_action.js 专门用于创建action对象</li>
<li>constant.js 放置容易写错的type值</li>
</ul>
<h1 id="redux异步编程"><a href="#redux异步编程" class="headerlink" title="redux异步编程"></a>redux异步编程</h1><h2 id="理解-5"><a href="#理解-5" class="headerlink" title="理解"></a>理解</h2><ol>
<li>redux默认是不能进行异步处理的,</li>
<li>某些时候应用中需要在redux中执行异步任务(ajax, 定时器)</li>
</ol>
<h2 id="使用异步中间件"><a href="#使用异步中间件" class="headerlink" title="使用异步中间件"></a>使用异步中间件</h2><p><code>npm install redux-thunk</code></p>
<h3 id="count-action-js"><a href="#count-action-js" class="headerlink" title="count_action.js"></a>count_action.js</h3><p>该模块专门为Count组件生成action对象<br>异步action，就是指action的值为函数,异步action中一般都会调用同步action，异步action不是必须要用的</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> &#123;<span class="variable constant_">INCREMENT</span>,<span class="variable constant_">DECREMENT</span>&#125; <span class="keyword">from</span> <span class="string">&#x27;./constant&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//同步action，就是指action的值为Object类型的一般对象</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">const</span> <span class="title function_">createIncrementAction</span> = data =&gt; (&#123;<span class="attr">type</span>:<span class="variable constant_">INCREMENT</span>,data&#125;)</span><br><span class="line"><span class="keyword">export</span> <span class="keyword">const</span> <span class="title function_">createDecrementAction</span> = data =&gt; (&#123;<span class="attr">type</span>:<span class="variable constant_">DECREMENT</span>,data&#125;)</span><br><span class="line"></span><br><span class="line"><span class="comment">//异步action，就是指action的值为函数,异步action中一般都会调用同步action，异步action不是必须要用的</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">const</span> <span class="title function_">createIncrementAsyncAction</span> = (<span class="params">data,time</span>) =&gt; &#123;</span><br><span class="line">	<span class="keyword">return</span> <span class="function">(<span class="params">dispatch</span>)=&gt;</span>&#123;</span><br><span class="line">		<span class="built_in">setTimeout</span>(<span class="function">()=&gt;</span>&#123;</span><br><span class="line">			<span class="title function_">dispatch</span>(<span class="title function_">createIncrementAction</span>(data))</span><br><span class="line">		&#125;,time)</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="store-js"><a href="#store-js" class="headerlink" title="store.js"></a>store.js</h3><blockquote>
<p>该模块专门用于暴露一个store对象，整个应用只有一个store对象</p>
</blockquote>
<p>在这里引入中间件</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//引入createStore，专门用于创建redux中最为核心的store对象</span></span><br><span class="line"><span class="keyword">import</span> &#123;createStore,applyMiddleware&#125; <span class="keyword">from</span> <span class="string">&#x27;redux&#x27;</span></span><br><span class="line"><span class="comment">//引入为Count组件服务的reducer</span></span><br><span class="line"><span class="keyword">import</span> countReducer <span class="keyword">from</span> <span class="string">&#x27;./count_reducer&#x27;</span></span><br><span class="line"><span class="comment">//引入redux-thunk，用于支持异步action</span></span><br><span class="line"><span class="keyword">import</span> thunk <span class="keyword">from</span> <span class="string">&#x27;redux-thunk&#x27;</span></span><br><span class="line"><span class="comment">//暴露store</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="title function_">createStore</span>(countReducer,<span class="title function_">applyMiddleware</span>(thunk))</span><br></pre></td></tr></table></figure>
<p>总结</p>
<ol>
<li>明确：延迟的动作不想交给组件自身，想交给action</li>
<li>何时需要异步action：想要对状态进行操作，但是具体的数据靠异步任务返回。</li>
<li>具体编码：</li>
<li>npm install redux-thunk，并配置在store中</li>
<li>创建action的函数不再返回一般对象，而是一个函数，该函数中写异步任务。</li>
<li>异步任务有结果后，分发一个同步的action去真正操作数据。</li>
<li>备注：异步action不是必须要写的，完全可以自己等待异步任务的结果了再去分发同步action。</li>
</ol>
<h1 id="react-redux"><a href="#react-redux" class="headerlink" title="react-redux"></a><a target="_blank" rel="noopener" href="https://so.csdn.net/so/search?from=pc_blog_highlight&q=react">react</a>-<a target="_blank" rel="noopener" href="https://so.csdn.net/so/search?from=pc_blog_highlight&q=redux">redux</a></h1><h2 id="理解-6"><a href="#理解-6" class="headerlink" title="理解"></a>理解</h2><ol>
<li>一个React插件库</li>
<li>专门用来简化React应用中使用redux</li>
</ol>
<h2 id="react-redux将所有组件分成两大类"><a href="#react-redux将所有组件分成两大类" class="headerlink" title="react-redux将所有组件分成两大类"></a><a target="_blank" rel="noopener" href="https://so.csdn.net/so/search?from=pc_blog_highlight&q=react">react</a>-<a target="_blank" rel="noopener" href="https://so.csdn.net/so/search?from=pc_blog_highlight&q=redux">redux</a>将所有组件分成两大类</h2><p><strong>UI组件</strong></p>
<p>1.<br>2. 只负责 UI 的呈现，不带有任何业务逻辑<br>3. 通过props接收数据(一般数据和函数)<br>4. 不使用任何 Redux 的 API<br>5. 一般保存在components文件夹下<br><strong>容器组件</strong></p>
<ol>
<li>负责管理数据和业务逻辑，不负责UI的呈现</li>
<li>使用 Redux 的 API</li>
<li>一般保存在containers文件夹下</li>
</ol>
<p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ca8e866ec5f14a8cb8eedeaaaca70199~tplv-k3u1fbpfcp-watermark.image" alt="20210617234345767.png"><br>相关API</p>
<ul>
<li><code>Provider</code>：让所有组件都可以得到state数据</li>
<li><code>connect</code>：用于包装 UI 组件生成容器组件</li>
<li><code>mapStateToprops</code>：将外部的数据（即state对象）转换为UI组件的标签属性</li>
<li><code>mapDispatchToProps</code>：将分发action的函数转换为UI组件的标签属性</li>
</ul>
<h2 id="基本使用"><a href="#基本使用" class="headerlink" title="基本使用"></a>基本使用</h2><h3 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h3><p><code>npm install react-redux</code></p>
<p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/40f895884c754b819092aa55215947ca~tplv-k3u1fbpfcp-watermark.image" alt="20210618095304942.png"></p>
<h3 id="components-x2F-Count-x2F-index-jsx"><a href="#components-x2F-Count-x2F-index-jsx" class="headerlink" title="components&#x2F;Count&#x2F;index.jsx"></a>components&#x2F;Count&#x2F;index.jsx</h3><p><strong>UI组件</strong></p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> <span class="title class_">React</span>, &#123; <span class="title class_">Component</span> &#125; <span class="keyword">from</span> <span class="string">&#x27;react&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="keyword">class</span> <span class="title class_">Count</span> <span class="keyword">extends</span> <span class="title class_ inherited__">Component</span> &#123;</span><br><span class="line">  <span class="comment">//加法</span></span><br><span class="line">  increment = <span class="function">()=&gt;</span>&#123;</span><br><span class="line">    <span class="keyword">const</span> &#123;value&#125; = <span class="variable language_">this</span>.<span class="property">selectNumber</span></span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">props</span>.<span class="title function_">jia</span>(value*<span class="number">1</span>)</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">//减法</span></span><br><span class="line">  decrement = <span class="function">()=&gt;</span>&#123;</span><br><span class="line">    <span class="keyword">const</span> &#123;value&#125; = <span class="variable language_">this</span>.<span class="property">selectNumber</span></span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">props</span>.<span class="title function_">jian</span>(value*<span class="number">1</span>)</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">//奇数再加</span></span><br><span class="line">  incrementIfOdd = <span class="function">()=&gt;</span>&#123;</span><br><span class="line">    <span class="keyword">const</span> &#123;value&#125; = <span class="variable language_">this</span>.<span class="property">selectNumber</span></span><br><span class="line">    <span class="keyword">if</span>(<span class="variable language_">this</span>.<span class="property">props</span>.<span class="property">count</span> % <span class="number">2</span> !== <span class="number">0</span>)&#123;</span><br><span class="line">      <span class="variable language_">this</span>.<span class="property">props</span>.<span class="title function_">jia</span>(value*<span class="number">1</span>)</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">//异步加</span></span><br><span class="line">  incrementAsync = <span class="function">()=&gt;</span>&#123;</span><br><span class="line">    <span class="keyword">const</span> &#123;value&#125; = <span class="variable language_">this</span>.<span class="property">selectNumber</span></span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">props</span>.<span class="title function_">jiaAsync</span>(value*<span class="number">1</span>,<span class="number">500</span>)</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="title function_">render</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="comment">//console.log(&#x27;UI组件接收到的props是&#x27;,this.props);</span></span><br><span class="line">    <span class="keyword">return</span> (</span><br><span class="line">      <span class="language-xml"><span class="tag">&lt;<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">h1</span>&gt;</span>当前求和为：&#123;this.props.count&#125;<span class="tag">&lt;/<span class="name">h1</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">select</span> <span class="attr">ref</span>=<span class="string">&#123;c</span> =&gt;</span> this.selectNumber = c&#125;&gt;</span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;<span class="name">option</span> <span class="attr">value</span>=<span class="string">&quot;1&quot;</span>&gt;</span>1<span class="tag">&lt;/<span class="name">option</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;<span class="name">option</span> <span class="attr">value</span>=<span class="string">&quot;2&quot;</span>&gt;</span>2<span class="tag">&lt;/<span class="name">option</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;<span class="name">option</span> <span class="attr">value</span>=<span class="string">&quot;3&quot;</span>&gt;</span>3<span class="tag">&lt;/<span class="name">option</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;/<span class="name">select</span>&gt;</span><span class="symbol">&amp;nbsp;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">button</span> <span class="attr">onClick</span>=<span class="string">&#123;this.increment&#125;</span>&gt;</span>+<span class="tag">&lt;/<span class="name">button</span>&gt;</span><span class="symbol">&amp;nbsp;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">button</span> <span class="attr">onClick</span>=<span class="string">&#123;this.decrement&#125;</span>&gt;</span>-<span class="tag">&lt;/<span class="name">button</span>&gt;</span><span class="symbol">&amp;nbsp;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">button</span> <span class="attr">onClick</span>=<span class="string">&#123;this.incrementIfOdd&#125;</span>&gt;</span>当前求和为奇数再加<span class="tag">&lt;/<span class="name">button</span>&gt;</span><span class="symbol">&amp;nbsp;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">button</span> <span class="attr">onClick</span>=<span class="string">&#123;this.incrementAsync&#125;</span>&gt;</span>异步加<span class="tag">&lt;/<span class="name">button</span>&gt;</span><span class="symbol">&amp;nbsp;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line">    )</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="containers-x2F-Count-x2F-index-jsx"><a href="#containers-x2F-Count-x2F-index-jsx" class="headerlink" title="containers&#x2F;Count&#x2F;index.jsx"></a>containers&#x2F;Count&#x2F;index.jsx</h3><p><strong>容器组件</strong></p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//引入Count的UI组件</span></span><br><span class="line"><span class="keyword">import</span> <span class="title class_">CountUI</span> <span class="keyword">from</span> <span class="string">&#x27;../../components/Count&#x27;</span></span><br><span class="line"><span class="comment">//引入action</span></span><br><span class="line"><span class="keyword">import</span> &#123;</span><br><span class="line">  createIncrementAction,</span><br><span class="line">  createDecrementAction,</span><br><span class="line">  createIncrementAsyncAction</span><br><span class="line">&#125; <span class="keyword">from</span> <span class="string">&#x27;../../redux/count_action&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//引入connect用于连接UI组件与redux</span></span><br><span class="line"><span class="keyword">import</span> &#123;connect&#125; <span class="keyword">from</span> <span class="string">&#x27;react-redux&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* </span></span><br><span class="line"><span class="comment">  1.mapStateToProps函数返回的是一个对象；</span></span><br><span class="line"><span class="comment">  2.返回的对象中的key就作为传递给UI组件props的key,value就作为传递给UI组件props的value</span></span><br><span class="line"><span class="comment">  3.mapStateToProps用于传递状态</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">mapStateToProps</span>(<span class="params">state</span>)&#123;</span><br><span class="line">  <span class="keyword">return</span> &#123;<span class="attr">count</span>:state&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* </span></span><br><span class="line"><span class="comment">  1.mapDispatchToProps函数返回的是一个对象；</span></span><br><span class="line"><span class="comment">  2.返回的对象中的key就作为传递给UI组件props的key,value就作为传递给UI组件props的value</span></span><br><span class="line"><span class="comment">  3.mapDispatchToProps用于传递操作状态的方法</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">mapDispatchToProps</span>(<span class="params">dispatch</span>)&#123;</span><br><span class="line">  <span class="keyword">return</span> &#123;</span><br><span class="line">    <span class="attr">jia</span>:<span class="function"><span class="params">number</span> =&gt;</span> <span class="title function_">dispatch</span>(<span class="title function_">createIncrementAction</span>(number)),</span><br><span class="line">    <span class="attr">jian</span>:<span class="function"><span class="params">number</span> =&gt;</span> <span class="title function_">dispatch</span>(<span class="title function_">createDecrementAction</span>(number)),</span><br><span class="line">    <span class="attr">jiaAsync</span>:<span class="function">(<span class="params">number,time</span>) =&gt;</span> <span class="title function_">dispatch</span>(<span class="title function_">createIncrementAsyncAction</span>(number,time)),</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//使用connect()()创建并暴露一个Count的容器组件</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="title function_">connect</span>(mapStateToProps,mapDispatchToProps)(<span class="title class_">CountUI</span>)</span><br></pre></td></tr></table></figure>
<h3 id="App-jsx-1"><a href="#App-jsx-1" class="headerlink" title="App.jsx"></a>App.jsx</h3><p><strong>给容器组件传递store</strong></p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> <span class="title class_">React</span>, &#123; <span class="title class_">Component</span> &#125; <span class="keyword">from</span> <span class="string">&#x27;react&#x27;</span></span><br><span class="line"><span class="keyword">import</span> <span class="title class_">Count</span> <span class="keyword">from</span> <span class="string">&#x27;./containers/Count&#x27;</span></span><br><span class="line"><span class="keyword">import</span> store <span class="keyword">from</span> <span class="string">&#x27;./redux/store&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="keyword">class</span> <span class="title class_">App</span> <span class="keyword">extends</span> <span class="title class_ inherited__">Component</span> &#123;</span><br><span class="line">  <span class="title function_">render</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> (</span><br><span class="line">      <span class="language-xml"><span class="tag">&lt;<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        &#123;/* 给容器组件传递store */&#125;</span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">Count</span> <span class="attr">store</span>=<span class="string">&#123;store&#125;</span> /&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line">    )</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>总结<br>明确两个概念：</p>
<ul>
<li>UI组件:不能使用任何 redux 的api，只负责页面的呈现、交互等。</li>
<li>容器组件：负责和 redux 通信，将结果交给UI组件。</li>
<li>如何创建一个容器组件————靠 react-redux 的 connect 函数</li>
<li>connect(mapStateToProps,mapDispatchToProps)(UI组件)<ul>
<li>mapStateToProps: 映射状态，返回值是一个对象</li>
<li>mapDispatchToProps: 映射操作状态的方法，返回值是一个对象</li>
</ul>
</li>
<li>备注1：容器组件中的store是靠props传进去的，而不是在容器组件中直接引入</li>
<li>备注2：mapDispatchToProps，也可以是一个对象【优化1】</li>
</ul>
<h2 id="优化"><a href="#优化" class="headerlink" title="优化"></a>优化</h2><h3 id="优化1-简写mapDispatchToProps"><a href="#优化1-简写mapDispatchToProps" class="headerlink" title="优化1 简写mapDispatchToProps"></a>优化1 简写<code>mapDispatchToProps</code></h3><p>&#x2F;&#x2F;使用connect()()创建并暴露一个Count的容器组件</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="title function_">connect</span>(</span><br><span class="line">  <span class="function"><span class="params">state</span> =&gt;</span> (&#123;<span class="attr">count</span>:state&#125;),</span><br><span class="line"></span><br><span class="line">  <span class="comment">//mapDispatchToProps的一般写法</span></span><br><span class="line">  <span class="comment">/* dispatch =&gt; (&#123;</span></span><br><span class="line"><span class="comment">    jia:number =&gt; dispatch(createIncrementAction(number)),</span></span><br><span class="line"><span class="comment">    jian:number =&gt; dispatch(createDecrementAction(number)),</span></span><br><span class="line"><span class="comment">    jiaAsync:(number,time) =&gt; dispatch(createIncrementAsyncAction(number,time)),</span></span><br><span class="line"><span class="comment">  &#125;) */</span></span><br><span class="line"></span><br><span class="line">  <span class="comment">//mapDispatchToProps的简写</span></span><br><span class="line">  &#123;</span><br><span class="line">    <span class="attr">jia</span>:createIncrementAction,</span><br><span class="line">    <span class="attr">jian</span>:createDecrementAction,</span><br><span class="line">    <span class="attr">jiaAsync</span>:createIncrementAsyncAction,</span><br><span class="line">  &#125;</span><br><span class="line">)(<span class="title class_">CountUI</span>)</span><br></pre></td></tr></table></figure>
<p>**容器组件可以检测redux中的状态改变，并渲染页面，所以不需要在index.js中检测了<br>不要在App.jsx中给子组件传递store了<br>**</p>
<h4 id="index-js-2"><a href="#index-js-2" class="headerlink" title="index.js"></a>index.js</h4><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> <span class="title class_">React</span> <span class="keyword">from</span> <span class="string">&#x27;react&#x27;</span></span><br><span class="line"><span class="keyword">import</span> <span class="title class_">ReactDOM</span> <span class="keyword">from</span> <span class="string">&#x27;react-dom&#x27;</span></span><br><span class="line"><span class="keyword">import</span> <span class="title class_">App</span> <span class="keyword">from</span> <span class="string">&#x27;./App&#x27;</span></span><br><span class="line"><span class="keyword">import</span> store <span class="keyword">from</span> <span class="string">&#x27;./redux/store&#x27;</span></span><br><span class="line"><span class="keyword">import</span> &#123;<span class="title class_">Provider</span>&#125; <span class="keyword">from</span> <span class="string">&#x27;react-redux&#x27;</span></span><br><span class="line"><span class="title class_">ReactDOM</span>.<span class="title function_">render</span>(</span><br><span class="line">	<span class="language-xml"><span class="tag">&lt;<span class="name">Provider</span> <span class="attr">store</span>=<span class="string">&#123;store&#125;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">		<span class="tag">&lt;<span class="name">App</span>/&gt;</span></span></span><br><span class="line"><span class="language-xml">	<span class="tag">&lt;/<span class="name">Provider</span>&gt;</span></span>,</span><br><span class="line">	<span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;root&#x27;</span>)</span><br><span class="line">)</span><br></pre></td></tr></table></figure>
<h3 id="优化3-整合UI组件和容器组件"><a href="#优化3-整合UI组件和容器组件" class="headerlink" title="优化3 整合UI组件和容器组件"></a>优化3 整合UI组件和容器组件</h3><p>每个组件两个文件夹太麻烦了，直接整合在一起就好了~</p>
<h4 id="containers-x2F-Count-x2F-index-jsx-1"><a href="#containers-x2F-Count-x2F-index-jsx-1" class="headerlink" title="containers&#x2F;Count&#x2F;index.jsx"></a><a href=""></a>containers&#x2F;Count&#x2F;index.jsx</h4><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> <span class="title class_">React</span>, &#123; <span class="title class_">Component</span> &#125; <span class="keyword">from</span> <span class="string">&#x27;react&#x27;</span></span><br><span class="line"><span class="comment">//引入action</span></span><br><span class="line"><span class="keyword">import</span> &#123;</span><br><span class="line">  createIncrementAction,</span><br><span class="line">  createDecrementAction,</span><br><span class="line">  createIncrementAsyncAction</span><br><span class="line">&#125; <span class="keyword">from</span> <span class="string">&#x27;../../redux/count_action&#x27;</span></span><br><span class="line"><span class="comment">//引入connect用于连接UI组件与redux</span></span><br><span class="line"><span class="keyword">import</span> &#123;connect&#125; <span class="keyword">from</span> <span class="string">&#x27;react-redux&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//定义UI组件</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Count</span> <span class="keyword">extends</span> <span class="title class_ inherited__">Component</span> &#123;</span><br><span class="line"></span><br><span class="line">  state = &#123;<span class="attr">carName</span>:<span class="string">&#x27;奔驰c63&#x27;</span>&#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">//加法</span></span><br><span class="line">  increment = <span class="function">()=&gt;</span>&#123;</span><br><span class="line">    <span class="keyword">const</span> &#123;value&#125; = <span class="variable language_">this</span>.<span class="property">selectNumber</span></span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">props</span>.<span class="title function_">jia</span>(value*<span class="number">1</span>)</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">//减法</span></span><br><span class="line">  decrement = <span class="function">()=&gt;</span>&#123;</span><br><span class="line">    <span class="keyword">const</span> &#123;value&#125; = <span class="variable language_">this</span>.<span class="property">selectNumber</span></span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">props</span>.<span class="title function_">jian</span>(value*<span class="number">1</span>)</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">//奇数再加</span></span><br><span class="line">  incrementIfOdd = <span class="function">()=&gt;</span>&#123;</span><br><span class="line">    <span class="keyword">const</span> &#123;value&#125; = <span class="variable language_">this</span>.<span class="property">selectNumber</span></span><br><span class="line">    <span class="keyword">if</span>(<span class="variable language_">this</span>.<span class="property">props</span>.<span class="property">count</span> % <span class="number">2</span> !== <span class="number">0</span>)&#123;</span><br><span class="line">      <span class="variable language_">this</span>.<span class="property">props</span>.<span class="title function_">jia</span>(value*<span class="number">1</span>)</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">//异步加</span></span><br><span class="line">  incrementAsync = <span class="function">()=&gt;</span>&#123;</span><br><span class="line">    <span class="keyword">const</span> &#123;value&#125; = <span class="variable language_">this</span>.<span class="property">selectNumber</span></span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">props</span>.<span class="title function_">jiaAsync</span>(value*<span class="number">1</span>,<span class="number">500</span>)</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="title function_">render</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="comment">//console.log(&#x27;UI组件接收到的props是&#x27;,this.props);</span></span><br><span class="line">    <span class="keyword">return</span> (</span><br><span class="line">      <span class="language-xml"><span class="tag">&lt;<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">h1</span>&gt;</span>当前求和为：&#123;this.props.count&#125;<span class="tag">&lt;/<span class="name">h1</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">select</span> <span class="attr">ref</span>=<span class="string">&#123;c</span> =&gt;</span> this.selectNumber = c&#125;&gt;</span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;<span class="name">option</span> <span class="attr">value</span>=<span class="string">&quot;1&quot;</span>&gt;</span>1<span class="tag">&lt;/<span class="name">option</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;<span class="name">option</span> <span class="attr">value</span>=<span class="string">&quot;2&quot;</span>&gt;</span>2<span class="tag">&lt;/<span class="name">option</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;<span class="name">option</span> <span class="attr">value</span>=<span class="string">&quot;3&quot;</span>&gt;</span>3<span class="tag">&lt;/<span class="name">option</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;/<span class="name">select</span>&gt;</span><span class="symbol">&amp;nbsp;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">button</span> <span class="attr">onClick</span>=<span class="string">&#123;this.increment&#125;</span>&gt;</span>+<span class="tag">&lt;/<span class="name">button</span>&gt;</span><span class="symbol">&amp;nbsp;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">button</span> <span class="attr">onClick</span>=<span class="string">&#123;this.decrement&#125;</span>&gt;</span>-<span class="tag">&lt;/<span class="name">button</span>&gt;</span><span class="symbol">&amp;nbsp;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">button</span> <span class="attr">onClick</span>=<span class="string">&#123;this.incrementIfOdd&#125;</span>&gt;</span>当前求和为奇数再加<span class="tag">&lt;/<span class="name">button</span>&gt;</span><span class="symbol">&amp;nbsp;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">button</span> <span class="attr">onClick</span>=<span class="string">&#123;this.incrementAsync&#125;</span>&gt;</span>异步加<span class="tag">&lt;/<span class="name">button</span>&gt;</span><span class="symbol">&amp;nbsp;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line">    )</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>使用connect()()创建并暴露一个Count的容器组件</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="title function_">connect</span>(</span><br><span class="line">  <span class="function"><span class="params">state</span> =&gt;</span> (&#123;<span class="attr">count</span>:state&#125;),</span><br><span class="line"></span><br><span class="line">  <span class="comment">//mapDispatchToProps的一般写法</span></span><br><span class="line">  <span class="comment">/* dispatch =&gt; (&#123;</span></span><br><span class="line"><span class="comment">    jia:number =&gt; dispatch(createIncrementAction(number)),</span></span><br><span class="line"><span class="comment">    jian:number =&gt; dispatch(createDecrementAction(number)),</span></span><br><span class="line"><span class="comment">    jiaAsync:(number,time) =&gt; dispatch(createIncrementAsyncAction(number,time)),</span></span><br><span class="line"><span class="comment">  &#125;) */</span></span><br><span class="line"></span><br><span class="line">  <span class="comment">//mapDispatchToProps的简写</span></span><br><span class="line">  &#123;</span><br><span class="line">    <span class="attr">jia</span>:createIncrementAction,</span><br><span class="line">    <span class="attr">jian</span>:createDecrementAction,</span><br><span class="line">    <span class="attr">jiaAsync</span>:createIncrementAsyncAction,</span><br><span class="line">  &#125;</span><br><span class="line">)(<span class="title class_">Count</span>)</span><br></pre></td></tr></table></figure>
<p>总结</p>
<ul>
<li>容器组件和UI组件整合一个文件</li>
<li>无需自己给容器组件传递store，给<App/>包裹一个<code>&lt;Provider store=&#123;store&#125;&gt;</code>即可。</li>
<li>使用了react-redux后也不用再自己检测redux中状态的改变了，容器组件可以自动完成这个工作。</li>
<li>mapDispatchToProps也可以简单的写成一个对象</li>
<li>一个组件要和redux“打交道”要经过哪几步？</li>
<li>定义好UI组件—不暴露</li>
<li>引入connect生成一个容器组件，并暴露，写法如下：<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="title function_">connect</span>(</span><br><span class="line">	<span class="function"><span class="params">state</span> =&gt;</span> (&#123;<span class="attr">key</span>:value&#125;), <span class="comment">//映射状态</span></span><br><span class="line">	&#123;<span class="attr">key</span>:xxxxxAction&#125; <span class="comment">//映射操作状态的方法</span></span><br><span class="line">)(<span class="variable constant_">UI</span>组件)</span><br></pre></td></tr></table></figure></li>
</ul>
<ol start="3">
<li>在UI组件中通过this.props.xxxxxxx读取和操作状态</li>
</ol>
<h3 id="store-js-1"><a href="#store-js-1" class="headerlink" title="store.js"></a>store.js</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* </span></span><br><span class="line"><span class="comment">	该文件专门用于暴露一个store对象，整个应用只有一个store对象</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//引入createStore，专门用于创建redux中最为核心的store对象</span></span><br><span class="line"><span class="keyword">import</span> &#123; createStore, applyMiddleware, combineReducers &#125; <span class="keyword">from</span> <span class="string">&quot;redux&quot;</span>;</span><br><span class="line"><span class="comment">//引入为Count组件服务的reducer</span></span><br><span class="line"><span class="keyword">import</span> countReducer <span class="keyword">from</span> <span class="string">&quot;./reducers/count&quot;</span>;</span><br><span class="line"><span class="comment">//引入为Count组件服务的reducer</span></span><br><span class="line"><span class="keyword">import</span> personReducer <span class="keyword">from</span> <span class="string">&quot;./reducers/person&quot;</span>;</span><br><span class="line"><span class="comment">//引入redux-thunk，用于支持异步action</span></span><br><span class="line"><span class="keyword">import</span> thunk <span class="keyword">from</span> <span class="string">&quot;redux-thunk&quot;</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 汇总所有的reducer变为一个总的reducer</span></span><br><span class="line"><span class="keyword">const</span> allReducer = <span class="title function_">combineReducers</span>(&#123;</span><br><span class="line">  <span class="attr">he</span>: countReducer,</span><br><span class="line">  <span class="attr">rens</span>: personReducer,</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="comment">//暴露store</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="title function_">createStore</span>(allReducer, <span class="title function_">applyMiddleware</span>(thunk));</span><br></pre></td></tr></table></figure>
<p>总结</p>
<ol>
<li>定义一个Pserson组件，和Count组件通过redux共享数据。</li>
<li>为Person组件编写：reducer、action，配置constant常量。</li>
<li>重点：Person的reducer和Count的reducer要使用combineReducers进行合并，合并后的总状态是一个对象！！！</li>
<li>交给store的是总reducer，最后注意在组件中取出状态的时候，记得“取到位”。<br>纯函数和高阶函数<br>reducer要求是一个纯函数，所以操作数组的时候，不能用push之类的方法</li>
</ol>
<h3 id="纯函数"><a href="#纯函数" class="headerlink" title="纯函数"></a>纯函数</h3><ol>
<li>一类特别的函数: 只要是同样的输入(实参)，必定得到同样的输出(返回)</li>
<li>必须遵守以下一些约束</li>
<li>不得改写参数数据</li>
<li>不会产生任何副作用，例如网络请求，输入和输出设备</li>
<li>不能调用Date.now()或者Math.random()等不纯的方法</li>
<li>redux的reducer函数必须是一个纯函数<br><strong>高阶函数</strong></li>
<li>理解: 一类特别的函数</li>
<li>情况1: 参数是函数</li>
<li>情况2: 返回是函数</li>
<li>常见的高阶函数:</li>
<li>定时器设置函数</li>
<li>数组的forEach()&#x2F;map()&#x2F;filter()&#x2F;reduce()&#x2F;find()&#x2F;bind()</li>
<li>promise</li>
<li>react-redux中的connect函数</li>
<li>作用: 能实现更加动态, 更加可扩展的功能</li>
</ol>
<h1 id="最终版"><a href="#最终版" class="headerlink" title="最终版"></a>最终版</h1><ol>
<li>所有变量名字要规范，尽量触发对象的简写形式。</li>
<li>reducers文件夹中，编写index.js专门用于汇总并暴露所有的reducer</li>
</ol>
<p><img src="https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/9e727339974f47b5afa6da56660ea426~tplv-k3u1fbpfcp-watermark.image" alt="202106181534064.png"></p>
<h2 id="containers-x2F-Count-x2F-index-jsx-2"><a href="#containers-x2F-Count-x2F-index-jsx-2" class="headerlink" title="containers&#x2F;Count&#x2F;index.jsx"></a>containers&#x2F;Count&#x2F;index.jsx</h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> <span class="title class_">React</span>, &#123; <span class="title class_">Component</span> &#125; <span class="keyword">from</span> <span class="string">&#x27;react&#x27;</span></span><br><span class="line"><span class="comment">//引入action</span></span><br><span class="line"><span class="keyword">import</span> &#123;</span><br><span class="line">  increment,</span><br><span class="line">  decrement,</span><br><span class="line">  incrementAsync</span><br><span class="line">&#125; <span class="keyword">from</span> <span class="string">&#x27;../../redux/actions/count&#x27;</span></span><br><span class="line"><span class="comment">//引入connect用于连接UI组件与redux</span></span><br><span class="line"><span class="keyword">import</span> &#123;connect&#125; <span class="keyword">from</span> <span class="string">&#x27;react-redux&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//定义UI组件</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Count</span> <span class="keyword">extends</span> <span class="title class_ inherited__">Component</span> &#123;</span><br><span class="line"></span><br><span class="line">  <span class="comment">//加法</span></span><br><span class="line">  increment = <span class="function">()=&gt;</span>&#123;</span><br><span class="line">    <span class="keyword">const</span> &#123;value&#125; = <span class="variable language_">this</span>.<span class="property">selectNumber</span></span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">props</span>.<span class="title function_">increment</span>(value*<span class="number">1</span>)</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">//减法</span></span><br><span class="line">  decrement = <span class="function">()=&gt;</span>&#123;</span><br><span class="line">    <span class="keyword">const</span> &#123;value&#125; = <span class="variable language_">this</span>.<span class="property">selectNumber</span></span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">props</span>.<span class="title function_">decrement</span>(value*<span class="number">1</span>)</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">//奇数再加</span></span><br><span class="line">  incrementIfOdd = <span class="function">()=&gt;</span>&#123;</span><br><span class="line">    <span class="keyword">const</span> &#123;value&#125; = <span class="variable language_">this</span>.<span class="property">selectNumber</span></span><br><span class="line">    <span class="keyword">if</span>(<span class="variable language_">this</span>.<span class="property">props</span>.<span class="property">count</span> % <span class="number">2</span> !== <span class="number">0</span>)&#123;</span><br><span class="line">      <span class="variable language_">this</span>.<span class="property">props</span>.<span class="title function_">increment</span>(value*<span class="number">1</span>)</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">//异步加</span></span><br><span class="line">  incrementAsync = <span class="function">()=&gt;</span>&#123;</span><br><span class="line">    <span class="keyword">const</span> &#123;value&#125; = <span class="variable language_">this</span>.<span class="property">selectNumber</span></span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">props</span>.<span class="title function_">incrementAsync</span>(value*<span class="number">1</span>,<span class="number">500</span>)</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="title function_">render</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="comment">//console.log(&#x27;UI组件接收到的props是&#x27;,this.props);</span></span><br><span class="line">    <span class="keyword">return</span> (</span><br><span class="line">      <span class="language-xml"><span class="tag">&lt;<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">h2</span>&gt;</span>我是Count组件,下方组件总人数为:&#123;this.props.renshu&#125;<span class="tag">&lt;/<span class="name">h2</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">h4</span>&gt;</span>当前求和为：&#123;this.props.count&#125;<span class="tag">&lt;/<span class="name">h4</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">select</span> <span class="attr">ref</span>=<span class="string">&#123;c</span> =&gt;</span> this.selectNumber = c&#125;&gt;</span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;<span class="name">option</span> <span class="attr">value</span>=<span class="string">&quot;1&quot;</span>&gt;</span>1<span class="tag">&lt;/<span class="name">option</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;<span class="name">option</span> <span class="attr">value</span>=<span class="string">&quot;2&quot;</span>&gt;</span>2<span class="tag">&lt;/<span class="name">option</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;<span class="name">option</span> <span class="attr">value</span>=<span class="string">&quot;3&quot;</span>&gt;</span>3<span class="tag">&lt;/<span class="name">option</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;/<span class="name">select</span>&gt;</span><span class="symbol">&amp;nbsp;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">button</span> <span class="attr">onClick</span>=<span class="string">&#123;this.increment&#125;</span>&gt;</span>+<span class="tag">&lt;/<span class="name">button</span>&gt;</span><span class="symbol">&amp;nbsp;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">button</span> <span class="attr">onClick</span>=<span class="string">&#123;this.decrement&#125;</span>&gt;</span>-<span class="tag">&lt;/<span class="name">button</span>&gt;</span><span class="symbol">&amp;nbsp;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">button</span> <span class="attr">onClick</span>=<span class="string">&#123;this.incrementIfOdd&#125;</span>&gt;</span>当前求和为奇数再加<span class="tag">&lt;/<span class="name">button</span>&gt;</span><span class="symbol">&amp;nbsp;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">button</span> <span class="attr">onClick</span>=<span class="string">&#123;this.incrementAsync&#125;</span>&gt;</span>异步加<span class="tag">&lt;/<span class="name">button</span>&gt;</span><span class="symbol">&amp;nbsp;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line">    )</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//使用connect()()创建并暴露一个Count的容器组件</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="title function_">connect</span>(</span><br><span class="line">  <span class="function"><span class="params">state</span> =&gt;</span> (&#123;</span><br><span class="line">    <span class="attr">count</span>:state.<span class="property">count</span>,</span><br><span class="line">    <span class="attr">personCount</span>:state.<span class="property">persons</span>.<span class="property">length</span></span><br><span class="line">  &#125;),</span><br><span class="line">  &#123;increment,decrement,incrementAsync&#125;</span><br><span class="line">)(<span class="title class_">Count</span>)</span><br></pre></td></tr></table></figure>
<h2 id="containers-x2F-Person-x2F-index-jsx"><a href="#containers-x2F-Person-x2F-index-jsx" class="headerlink" title="containers&#x2F;Person&#x2F;index.jsx"></a>containers&#x2F;Person&#x2F;index.jsx</h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> <span class="title class_">React</span>, &#123; <span class="title class_">Component</span> &#125; <span class="keyword">from</span> <span class="string">&#x27;react&#x27;</span></span><br><span class="line"><span class="keyword">import</span> &#123;nanoid&#125; <span class="keyword">from</span> <span class="string">&#x27;nanoid&#x27;</span></span><br><span class="line"><span class="keyword">import</span> &#123;connect&#125; <span class="keyword">from</span> <span class="string">&#x27;react-redux&#x27;</span></span><br><span class="line"><span class="keyword">import</span> &#123;addPerson&#125; <span class="keyword">from</span> <span class="string">&#x27;../../redux/actions/person&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Person</span> <span class="keyword">extends</span> <span class="title class_ inherited__">Component</span> &#123;</span><br><span class="line"></span><br><span class="line">  addPerson = <span class="function">()=&gt;</span>&#123;</span><br><span class="line">    <span class="keyword">const</span> name = <span class="variable language_">this</span>.<span class="property">nameNode</span>.<span class="property">value</span></span><br><span class="line">    <span class="keyword">const</span> age = <span class="variable language_">this</span>.<span class="property">ageNode</span>.<span class="property">value</span>*<span class="number">1</span></span><br><span class="line">    <span class="keyword">const</span> personObj = &#123;<span class="attr">id</span>:<span class="title function_">nanoid</span>(),name,age&#125;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">props</span>.<span class="title function_">addPerson</span>(personObj)</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">nameNode</span>.<span class="property">value</span> = <span class="string">&#x27;&#x27;</span></span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">ageNode</span>.<span class="property">value</span> = <span class="string">&#x27;&#x27;</span></span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="title function_">render</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> (</span><br><span class="line">      <span class="language-xml"><span class="tag">&lt;<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">h2</span>&gt;</span>我是Person组件,上方组件求和为&#123;this.props.count&#125;<span class="tag">&lt;/<span class="name">h2</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">input</span> <span class="attr">ref</span>=<span class="string">&#123;c</span>=&gt;</span>this.nameNode = c&#125; type=&quot;text&quot; placeholder=&quot;输入名字&quot;/&gt;</span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">input</span> <span class="attr">ref</span>=<span class="string">&#123;c</span>=&gt;</span>this.ageNode = c&#125; type=&quot;text&quot; placeholder=&quot;输入年龄&quot;/&gt;</span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">button</span> <span class="attr">onClick</span>=<span class="string">&#123;this.addPerson&#125;</span>&gt;</span>添加<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">ul</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          &#123;</span></span><br><span class="line"><span class="language-xml">            this.props.persons.map((p)=&gt;&#123;</span></span><br><span class="line"><span class="language-xml">              return <span class="tag">&lt;<span class="name">li</span> <span class="attr">key</span>=<span class="string">&#123;p.id&#125;</span>&gt;</span>&#123;p.name&#125;--&#123;p.age&#125;<span class="tag">&lt;/<span class="name">li</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">            &#125;)</span></span><br><span class="line"><span class="language-xml">          &#125;</span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;/<span class="name">ul</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line">    )</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="title function_">connect</span>(</span><br><span class="line">  <span class="function"><span class="params">state</span> =&gt;</span> (&#123;</span><br><span class="line">    <span class="attr">persons</span>:state.<span class="property">persons</span>,</span><br><span class="line">    <span class="attr">count</span>:state.<span class="property">count</span></span><br><span class="line">  &#125;),<span class="comment">//映射状态</span></span><br><span class="line">  &#123;addPerson&#125;<span class="comment">//映射操作状态的方法</span></span><br><span class="line">)(<span class="title class_">Person</span>)</span><br></pre></td></tr></table></figure>
<h2 id="redux-x2F-actions-x2F-count-js"><a href="#redux-x2F-actions-x2F-count-js" class="headerlink" title="redux&#x2F;actions&#x2F;count.js"></a>redux&#x2F;actions&#x2F;count.js</h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* </span></span><br><span class="line"><span class="comment">  该文件专门为Count组件生成action对象</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="keyword">import</span> &#123; <span class="variable constant_">INCREMENT</span>, <span class="variable constant_">DECREMENT</span> &#125; <span class="keyword">from</span> <span class="string">&quot;../constant&quot;</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">//同步action，就是指action的值为Object类型的一般对象</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">const</span> <span class="title function_">increment</span> = (<span class="params">data</span>) =&gt; (&#123; <span class="attr">type</span>: <span class="variable constant_">INCREMENT</span>, data &#125;);</span><br><span class="line"><span class="keyword">export</span> <span class="keyword">const</span> <span class="title function_">decrement</span> = (<span class="params">data</span>) =&gt; (&#123; <span class="attr">type</span>: <span class="variable constant_">DECREMENT</span>, data &#125;);</span><br><span class="line"></span><br><span class="line"><span class="comment">//异步action，就是指action的值为函数,异步action中一般都会调用同步action，异步action不是必须要用的。</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">const</span> <span class="title function_">incrementAsync</span> = (<span class="params">data, time</span>) =&gt; &#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="function">(<span class="params">dispatch</span>) =&gt;</span> &#123;</span><br><span class="line">    <span class="built_in">setTimeout</span>(<span class="function">() =&gt;</span> &#123;</span><br><span class="line">      <span class="title function_">dispatch</span>(<span class="title function_">increment</span>(data));</span><br><span class="line">    &#125;, time);</span><br><span class="line">  &#125;;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>
<h2 id="redux-x2F-action-x2F-person-js"><a href="#redux-x2F-action-x2F-person-js" class="headerlink" title="redux&#x2F;action&#x2F;person.js"></a>redux&#x2F;action&#x2F;person.js</h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> &#123; <span class="variable constant_">ADD_PERSON</span> &#125; <span class="keyword">from</span> <span class="string">&quot;../constant&quot;</span>;</span><br><span class="line"><span class="comment">//创建增加一个人的action动作对象</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">const</span> <span class="title function_">addPerson</span> = (<span class="params">personObj</span>) =&gt; (&#123; <span class="attr">type</span>: <span class="variable constant_">ADD_PERSON</span>, <span class="attr">data</span>: personObj &#125;);</span><br></pre></td></tr></table></figure>
<h2 id="redux-x2F-reducers-x2F-count-js"><a href="#redux-x2F-reducers-x2F-count-js" class="headerlink" title="redux&#x2F;reducers&#x2F;count.js"></a>redux&#x2F;reducers&#x2F;count.js</h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* </span></span><br><span class="line"><span class="comment">  1.该文件是用于创建一个为Count组件服务的reducer，reducer的本质就是一个函数</span></span><br><span class="line"><span class="comment">  2.reducer函数会接到两个参数，分别为：之前的状态(preState)，动作对象(action)</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="keyword">import</span> &#123; <span class="variable constant_">INCREMENT</span>, <span class="variable constant_">DECREMENT</span> &#125; <span class="keyword">from</span> <span class="string">&quot;../constant&quot;</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> initState = <span class="number">0</span>; <span class="comment">//初始化状态</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="keyword">function</span> <span class="title function_">countReducer</span>(<span class="params">preState = initState, action</span>) &#123;</span><br><span class="line">  <span class="comment">// console.log(&#x27;countReducer@#@#@#&#x27;);</span></span><br><span class="line">  <span class="comment">//从action对象中获取：type、data</span></span><br><span class="line">  <span class="keyword">const</span> &#123; type, data &#125; = action;</span><br><span class="line">  <span class="comment">//根据type决定如何加工数据</span></span><br><span class="line">  <span class="keyword">switch</span> (type) &#123;</span><br><span class="line">    <span class="keyword">case</span> <span class="attr">INCREMENT</span>: <span class="comment">//如果是加</span></span><br><span class="line">      <span class="keyword">return</span> preState + data;</span><br><span class="line">    <span class="keyword">case</span> <span class="attr">DECREMENT</span>: <span class="comment">//若果是减</span></span><br><span class="line">      <span class="keyword">return</span> preState - data;</span><br><span class="line">    <span class="attr">default</span>:</span><br><span class="line">      <span class="keyword">return</span> preState;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="redux-x2F-reducers-x2F-person-js"><a href="#redux-x2F-reducers-x2F-person-js" class="headerlink" title="redux&#x2F;reducers&#x2F;person.js"></a>redux&#x2F;reducers&#x2F;person.js</h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> &#123; <span class="variable constant_">ADD_PERSON</span> &#125; <span class="keyword">from</span> <span class="string">&quot;../constant&quot;</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">//初始化人的列表</span></span><br><span class="line"><span class="keyword">const</span> initState = [&#123; <span class="attr">id</span>: <span class="string">&quot;001&quot;</span>, <span class="attr">name</span>: <span class="string">&quot;tom&quot;</span>, <span class="attr">age</span>: <span class="number">18</span> &#125;];</span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="keyword">function</span> <span class="title function_">personReducer</span>(<span class="params">preState = initState, action</span>) &#123;</span><br><span class="line">  <span class="keyword">const</span> &#123; type, data &#125; = action;</span><br><span class="line">  <span class="keyword">switch</span> (type) &#123;</span><br><span class="line">    <span class="keyword">case</span> <span class="attr">ADD_PERSON</span>: <span class="comment">//若是添加一个人</span></span><br><span class="line">      <span class="comment">//preState.unshift(data) //此处不可以这样写，这样会导致preState被改写了，personReducer就不是纯函数了。</span></span><br><span class="line">      <span class="keyword">return</span> [data, ...preState];</span><br><span class="line">    <span class="attr">default</span>:</span><br><span class="line">      <span class="keyword">return</span> preState;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="redux-x2F-reducers-x2F-index-js"><a href="#redux-x2F-reducers-x2F-index-js" class="headerlink" title="redux&#x2F;reducers&#x2F;index.js"></a>redux&#x2F;reducers&#x2F;index.js</h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* </span></span><br><span class="line"><span class="comment">	该文件用于汇总所有的reducer为一个总的reducer</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="comment">//引入combineReducers，用于汇总多个reducer</span></span><br><span class="line"><span class="keyword">import</span> &#123; combineReducers &#125; <span class="keyword">from</span> <span class="string">&quot;redux&quot;</span>;</span><br><span class="line"><span class="comment">//引入为Count组件服务的reducer</span></span><br><span class="line"><span class="keyword">import</span> count <span class="keyword">from</span> <span class="string">&quot;./count&quot;</span>;</span><br><span class="line"><span class="comment">//引入为Person组件服务的reducer</span></span><br><span class="line"><span class="keyword">import</span> persons <span class="keyword">from</span> <span class="string">&quot;./person&quot;</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">//汇总所有的reducer变为一个总的reducer</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="title function_">combineReducers</span>(&#123;</span><br><span class="line">  count,</span><br><span class="line">  persons,</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>
<h2 id="redux-x2F-constant-js-1"><a href="#redux-x2F-constant-js-1" class="headerlink" title="redux&#x2F;constant.js"></a>redux&#x2F;constant.js</h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* </span></span><br><span class="line"><span class="comment">	该模块是用于定义action对象中type类型的常量值，目的只有一个：便于管理的同时防止程序员单词写错</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">const</span> <span class="variable constant_">INCREMENT</span> = <span class="string">&quot;increment&quot;</span>;</span><br><span class="line"><span class="keyword">export</span> <span class="keyword">const</span> <span class="variable constant_">DECREMENT</span> = <span class="string">&quot;decrement&quot;</span>;</span><br><span class="line"><span class="keyword">export</span> <span class="keyword">const</span> <span class="variable constant_">ADD_PERSON</span> = <span class="string">&quot;add_person&quot;</span>;</span><br></pre></td></tr></table></figure>
<h2 id="redux-x2F-store-js-1"><a href="#redux-x2F-store-js-1" class="headerlink" title="redux&#x2F;store.js"></a>redux&#x2F;store.js</h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* </span></span><br><span class="line"><span class="comment">	该文件专门用于暴露一个store对象，整个应用只有一个store对象</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="comment">//引入createStore，专门用于创建redux中最为核心的store对象</span></span><br><span class="line"><span class="keyword">import</span> &#123; createStore, applyMiddleware &#125; <span class="keyword">from</span> <span class="string">&quot;redux&quot;</span>;</span><br><span class="line"><span class="comment">//引入汇总之后的reducer</span></span><br><span class="line"><span class="keyword">import</span> reducer <span class="keyword">from</span> <span class="string">&quot;./reducers&quot;</span>;</span><br><span class="line"><span class="comment">//引入redux-thunk，用于支持异步action</span></span><br><span class="line"><span class="keyword">import</span> thunk <span class="keyword">from</span> <span class="string">&quot;redux-thunk&quot;</span>;</span><br><span class="line"><span class="comment">//引入redux-devtools-extension</span></span><br><span class="line"><span class="keyword">import</span> &#123; composeWithDevTools &#125; <span class="keyword">from</span> <span class="string">&quot;redux-devtools-extension&quot;</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">//暴露store</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="title function_">createStore</span>(</span><br><span class="line">  reducer,</span><br><span class="line">  <span class="title function_">composeWithDevTools</span>(<span class="title function_">applyMiddleware</span>(thunk))</span><br><span class="line">);</span><br></pre></td></tr></table></figure>
<h2 id="App-jsx-2"><a href="#App-jsx-2" class="headerlink" title="App.jsx"></a>App.jsx</h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> <span class="title class_">React</span>, &#123; <span class="title class_">Component</span> &#125; <span class="keyword">from</span> <span class="string">&#x27;react&#x27;</span></span><br><span class="line"><span class="keyword">import</span> <span class="title class_">Count</span> <span class="keyword">from</span> <span class="string">&#x27;./containers/Count&#x27;</span> <span class="comment">//引入的Count的容器组件</span></span><br><span class="line"><span class="keyword">import</span> <span class="title class_">Person</span> <span class="keyword">from</span> <span class="string">&#x27;./containers/Person&#x27;</span> <span class="comment">//引入的Person的容器组件</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="keyword">class</span> <span class="title class_">App</span> <span class="keyword">extends</span> <span class="title class_ inherited__">Component</span> &#123;</span><br><span class="line">  <span class="title function_">render</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> (</span><br><span class="line">      <span class="language-xml"><span class="tag">&lt;<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">Count</span>/&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">hr</span>/&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">Person</span>/&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line">    )</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="index-js-3"><a href="#index-js-3" class="headerlink" title="index.js"></a>index.js</h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> <span class="title class_">React</span> <span class="keyword">from</span> <span class="string">&quot;react&quot;</span>;</span><br><span class="line"><span class="keyword">import</span> <span class="title class_">ReactDOM</span> <span class="keyword">from</span> <span class="string">&quot;react-dom&quot;</span>;</span><br><span class="line"><span class="keyword">import</span> <span class="title class_">App</span> <span class="keyword">from</span> <span class="string">&quot;./App&quot;</span>;</span><br><span class="line"><span class="keyword">import</span> store <span class="keyword">from</span> <span class="string">&quot;./redux/store&quot;</span>;</span><br><span class="line"><span class="keyword">import</span> &#123; <span class="title class_">Provider</span> &#125; <span class="keyword">from</span> <span class="string">&quot;react-redux&quot;</span>;</span><br><span class="line"></span><br><span class="line"><span class="title class_">ReactDOM</span>.<span class="title function_">render</span>(</span><br><span class="line">  <span class="comment">/* 此处需要用Provider包裹App，目的是让App所有的后代容器组件都能接收到store */</span></span><br><span class="line">  <span class="language-xml"><span class="tag">&lt;<span class="name">Provider</span> <span class="attr">store</span>=<span class="string">&#123;store&#125;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">    <span class="tag">&lt;<span class="name">App</span> /&gt;</span></span></span><br><span class="line"><span class="language-xml">  <span class="tag">&lt;/<span class="name">Provider</span>&gt;</span></span>,</span><br><span class="line">  <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&quot;root&quot;</span>)</span><br><span class="line">);</span><br></pre></td></tr></table></figure>
<h1 id="【React】拓展"><a href="#【React】拓展" class="headerlink" title="【React】拓展"></a>【React】拓展</h1><ol>
<li>setState</li>
<li>路由组件懒加载</li>
<li>Hooks</li>
<li>Context</li>
<li>PureComponent</li>
<li>插槽</li>
<li>错误边界</li>
<li>组件通信方式</li>
<li> setState</li>
</ol>
<h2 id="setState"><a href="#setState" class="headerlink" title="setState"></a>setState</h2><p><code>setState</code>更新状态其实有两种写法<br>setState这个方法在调用的时候是同步的，但是引起<a target="_blank" rel="noopener" href="https://so.csdn.net/so/search?from=pc_blog_highlight&q=React">React</a>的状态更新是异步的<br>【React状态更新是异步的】</p>
<h2 id="对象式"><a href="#对象式" class="headerlink" title="对象式"></a>对象式</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">setState(stateChange, [callback])</span><br></pre></td></tr></table></figure>
<ol>
<li><code>stateChange</code>为状态改变<strong>对象</strong> (该对象可以体现出状态的更改)</li>
<li><code>callback</code>是可选的<strong>回调函数</strong>, 它在状态更新完毕、界面也更新后(<code>render</code>调用后)才被调用【异步更新后调用，可以拿到更新后的状态的值】<br>之前一直写的，就是直接传一个对象<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">this.setState(&#123; count: this.state.count+1 &#125;)</span><br></pre></td></tr></table></figure></li>
</ol>
<h2 id="函数式"><a href="#函数式" class="headerlink" title="函数式"></a>函数式</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">setState(updater, [callback])</span><br></pre></td></tr></table></figure>
<ol>
<li><code>updater</code>为返回<code>stateChange</code>对象的函数【返回值是对象】</li>
<li><code>updater</code>可以接收到<code>state</code>和<code>props</code></li>
<li><code>callback</code>是可选的回调函数, 它在状态更新、界面也更新后(<code>render</code>调用后)才被调用【和对象式是一样的】<br>传的时候回调函数，可以接收到state和props，函数的返回值是设置状态的对象<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">setState(state =&gt; (&#123;count: state.count+1&#125;)) </span><br></pre></td></tr></table></figure>
总结</li>
</ol>
<ul>
<li>对象式的setState是函数式的setState的简写方式【语法糖】</li>
<li>使用原则</li>
<li>如果新状态不依赖于原状态【使用对象方式】</li>
<li>如果新状态依赖于原状态 【使用函数方式】</li>
<li>如果需要在setState()执行后，获取最新的状态数据，可以在第二个callback函数中读取到异步更新的最新值</li>
</ul>
<h1 id="路由组件的懒加载-lazyLoad"><a href="#路由组件的懒加载-lazyLoad" class="headerlink" title="路由组件的懒加载 lazyLoad"></a>路由组件的懒加载 lazyLoad</h1><p>用的时候才加载，一般是路由组件进行懒加载<br>如果不用路由懒加载，页面在第一次进入的时候，就请求了所有组件的数据，如果组件过多，过多的请求这就没有必要了，应该是用户按哪个链接再请求哪个组件</p>
<p>通过React的lazy函数配合import()函数动态加载路由组件【路由组件代码会被分开打包】<br>通过<Suspense>指定在加载得到路由打包文件前显示一个自定义loading界</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> <span class="title class_">React</span>, &#123; <span class="title class_">Component</span>, lazy, <span class="title class_">Suspense</span>&#125; <span class="keyword">from</span> <span class="string">&#x27;react&#x27;</span></span><br><span class="line"><span class="keyword">import</span> &#123;<span class="title class_">NavLink</span>,<span class="title class_">Route</span>&#125; <span class="keyword">from</span> <span class="string">&#x27;react-router-dom&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// import Home from &#x27;./Home&#x27;</span></span><br><span class="line"><span class="comment">// import About from &#x27;./About&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> <span class="title class_">Loading</span> <span class="keyword">from</span> <span class="string">&#x27;./Loading&#x27;</span></span><br><span class="line"><span class="keyword">const</span> <span class="title class_">Home</span> = <span class="title function_">lazy</span>(<span class="function">()=&gt;</span> <span class="title function_">import</span>(<span class="string">&#x27;./Home&#x27;</span>) )</span><br><span class="line"><span class="keyword">const</span> <span class="title class_">About</span> = <span class="title function_">lazy</span>(<span class="function">()=&gt;</span> <span class="title function_">import</span>(<span class="string">&#x27;./About&#x27;</span>))</span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="keyword">class</span> <span class="title class_">Demo</span> <span class="keyword">extends</span> <span class="title class_ inherited__">Component</span> &#123;</span><br><span class="line">  <span class="title function_">render</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> (</span><br><span class="line">      <span class="language-xml"><span class="tag">&lt;<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">div</span> <span class="attr">className</span>=<span class="string">&quot;row&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;<span class="name">div</span> <span class="attr">className</span>=<span class="string">&quot;col-xs-offset-2 col-xs-8&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">            <span class="tag">&lt;<span class="name">div</span> <span class="attr">className</span>=<span class="string">&quot;page-header&quot;</span>&gt;</span><span class="tag">&lt;<span class="name">h2</span>&gt;</span>React Router Demo<span class="tag">&lt;/<span class="name">h2</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">div</span> <span class="attr">className</span>=<span class="string">&quot;row&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;<span class="name">div</span> <span class="attr">className</span>=<span class="string">&quot;col-xs-2 col-xs-offset-2&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">            <span class="tag">&lt;<span class="name">div</span> <span class="attr">className</span>=<span class="string">&quot;list-group&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">              &#123;/* 在React中靠路由链接实现切换组件--编写路由链接 */&#125;</span></span><br><span class="line"><span class="language-xml">              <span class="tag">&lt;<span class="name">NavLink</span> <span class="attr">className</span>=<span class="string">&quot;list-group-item&quot;</span> <span class="attr">to</span>=<span class="string">&quot;/about&quot;</span>&gt;</span>About<span class="tag">&lt;/<span class="name">NavLink</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">              <span class="tag">&lt;<span class="name">NavLink</span> <span class="attr">className</span>=<span class="string">&quot;list-group-item&quot;</span> <span class="attr">to</span>=<span class="string">&quot;/home&quot;</span>&gt;</span>Home<span class="tag">&lt;/<span class="name">NavLink</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">            <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;<span class="name">div</span> <span class="attr">className</span>=<span class="string">&quot;col-xs-6&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">            <span class="tag">&lt;<span class="name">div</span> <span class="attr">className</span>=<span class="string">&quot;panel&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">              <span class="tag">&lt;<span class="name">div</span> <span class="attr">className</span>=<span class="string">&quot;panel-body&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">                <span class="tag">&lt;<span class="name">Suspense</span> <span class="attr">fallback</span>=<span class="string">&#123;</span>&lt;<span class="attr">Loading</span>/&gt;</span>&#125;&gt;</span></span><br><span class="line"><span class="language-xml">                  &#123;/* 注册路由 */&#125;</span></span><br><span class="line"><span class="language-xml">                  <span class="tag">&lt;<span class="name">Route</span> <span class="attr">path</span>=<span class="string">&quot;/about&quot;</span> <span class="attr">component</span>=<span class="string">&#123;About&#125;/</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">                  <span class="tag">&lt;<span class="name">Route</span> <span class="attr">path</span>=<span class="string">&quot;/home&quot;</span> <span class="attr">component</span>=<span class="string">&#123;Home&#125;/</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">                <span class="tag">&lt;/<span class="name">Suspense</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">              <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">            <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line">    )</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h1 id="Hooks"><a href="#Hooks" class="headerlink" title="Hooks"></a>Hooks</h1><p>React Hook&#x2F;Hooks是什么?<br>Hook 是 React 16.8 的新增特性。<br>它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。【函数式组件】</p>
<p><strong>三个常用的Hook</strong></p>
<ol>
<li>State Hook: React.useState()</li>
<li>Effect Hook: React.useEffect()</li>
<li>Ref Hook: React.useRef()<br><strong>State Hook</strong></li>
</ol>
<p>State Hook让函数组件也可以有state状态, 并进行状态数据的读写操作<br>语法: const [xxx, setXxx] &#x3D; React.useState(initValue)</p>
<p>useState()说明:<br>参数: 第一次初始化指定的值在内部作缓存<br>返回值: 包含2个元素的数组, 第1个为内部当前状态值, 第2个为更新状态值的函数</p>
<p><strong>setXxx()2种写法:</strong></p>
<p>setXxx(newValue): 参数为非函数值, 直接指定新的状态值, 内部用其覆盖原来的状态值<br>setXxx(value &#x3D;&gt; newValue): 参数为函数, 接收原本的状态值, 返回新的状态值, 内部用其覆盖原来的状态值</p>
<p><strong>Effect Hook</strong></p>
<p>Effect Hook 可以让你在函数组件中执行副作用操作(用于模拟类组件中的生命周期钩子)</p>
<p><code>React中的副作用操作:</code></p>
<ul>
<li>发ajax请求数据获取</li>
<li>设置订阅 &#x2F; 启动定时器</li>
<li>手动更改真实DOM</li>
</ul>
<p>语法和说明:</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="title function_">useEffect</span>(<span class="function">() =&gt;</span> &#123; </span><br><span class="line">  <span class="comment">// 在此可以执行任何带副作用操作【挂载+更新】</span></span><br><span class="line">  <span class="keyword">return</span> <span class="function">() =&gt;</span> &#123; <span class="comment">// 在组件卸载前执行</span></span><br><span class="line">    <span class="comment">// 在此做一些收尾工作, 比如清除定时器/取消订阅等【卸载前】</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;, [stateValue]) <span class="comment">// 如果指定的是[], 回调函数只会在第一次render()后执行</span></span><br></pre></td></tr></table></figure>
<p>可以把 useEffect Hook 看做如下三个函数的组合</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="title function_">componentDidMount</span>()</span><br><span class="line"><span class="title function_">componentDidUpdate</span>()</span><br><span class="line"><span class="title function_">componentWillUnmount</span>() </span><br></pre></td></tr></table></figure>
<p> Ref Hook<br>Ref Hook可以在函数组件中存储&#x2F;查找组件内的标签或任意其它数据<br>语法: const refContainer &#x3D; useRef()<br>作用:保存标签对象,功能与React.createRef()一样<br>代码示例</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> <span class="title class_">React</span> <span class="keyword">from</span> <span class="string">&#x27;react&#x27;</span></span><br><span class="line"><span class="keyword">import</span> <span class="title class_">ReactDOM</span> <span class="keyword">from</span> <span class="string">&#x27;react-dom&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//类式组件</span></span><br><span class="line"><span class="comment">/* class Demo extends React.Component &#123;</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">  state = &#123;count:0&#125;</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">  myRef = React.createRef()</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">  add = ()=&gt;&#123;</span></span><br><span class="line"><span class="comment">    this.setState(state =&gt; (&#123;count:state.count+1&#125;))</span></span><br><span class="line"><span class="comment">  &#125;</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">  unmount = ()=&gt;&#123;</span></span><br><span class="line"><span class="comment">    ReactDOM.unmountComponentAtNode(document.getElementById(&#x27;root&#x27;))</span></span><br><span class="line"><span class="comment">  &#125;</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">  show = ()=&gt;&#123;</span></span><br><span class="line"><span class="comment">    alert(this.myRef.current.value)</span></span><br><span class="line"><span class="comment">  &#125;</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">  componentDidMount()&#123;</span></span><br><span class="line"><span class="comment">    this.timer = setInterval(()=&gt;&#123;</span></span><br><span class="line"><span class="comment">      this.setState( state =&gt; (&#123;count:state.count+1&#125;))</span></span><br><span class="line"><span class="comment">    &#125;,1000)</span></span><br><span class="line"><span class="comment">  &#125;</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">  componentWillUnmount()&#123;</span></span><br><span class="line"><span class="comment">    clearInterval(this.timer)</span></span><br><span class="line"><span class="comment">  &#125;</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">  render() &#123;</span></span><br><span class="line"><span class="comment">    return (</span></span><br><span class="line"><span class="comment">      &lt;div&gt;</span></span><br><span class="line"><span class="comment">        &lt;input type=&quot;text&quot; ref=&#123;this.myRef&#125;/&gt;</span></span><br><span class="line"><span class="comment">        &lt;h2&gt;当前求和为&#123;this.state.count&#125;&lt;/h2&gt;</span></span><br><span class="line"><span class="comment">        &lt;button onClick=&#123;this.add&#125;&gt;点我+1&lt;/button&gt;</span></span><br><span class="line"><span class="comment">        &lt;button onClick=&#123;this.unmount&#125;&gt;卸载组件&lt;/button&gt;</span></span><br><span class="line"><span class="comment">        &lt;button onClick=&#123;this.show&#125;&gt;点击提示数据&lt;/button&gt;</span></span><br><span class="line"><span class="comment">      &lt;/div&gt;</span></span><br><span class="line"><span class="comment">    )</span></span><br><span class="line"><span class="comment">  &#125;</span></span><br><span class="line"><span class="comment">&#125; */</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">Demo</span>(<span class="params"></span>)&#123;</span><br><span class="line">  <span class="comment">//console.log(&#x27;Demo&#x27;);</span></span><br><span class="line"></span><br><span class="line">  <span class="keyword">const</span> [count,setCount] = <span class="title class_">React</span>.<span class="title function_">useState</span>(<span class="number">0</span>)</span><br><span class="line">  <span class="keyword">const</span> myRef = <span class="title class_">React</span>.<span class="title function_">useRef</span>()</span><br><span class="line"></span><br><span class="line">  <span class="title class_">React</span>.<span class="title function_">useEffect</span>(<span class="function">()=&gt;</span>&#123;</span><br><span class="line">    <span class="keyword">let</span> timer = <span class="built_in">setInterval</span>(<span class="function">()=&gt;</span>&#123;</span><br><span class="line">      <span class="title function_">setCount</span>(<span class="function"><span class="params">count</span> =&gt;</span> count+<span class="number">1</span> )</span><br><span class="line">    &#125;,<span class="number">1000</span>)</span><br><span class="line">    <span class="keyword">return</span> <span class="function">()=&gt;</span>&#123;</span><br><span class="line">      <span class="built_in">clearInterval</span>(timer)</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;,[])</span><br><span class="line"></span><br><span class="line">  <span class="comment">//加的回调</span></span><br><span class="line">  <span class="keyword">function</span> <span class="title function_">add</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="comment">//setCount(count+1) //第一种写法</span></span><br><span class="line">    <span class="title function_">setCount</span>(<span class="function"><span class="params">count</span> =&gt;</span> count+<span class="number">1</span> )</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">//提示输入的回调</span></span><br><span class="line">  <span class="keyword">function</span> <span class="title function_">show</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="title function_">alert</span>(myRef.<span class="property">current</span>.<span class="property">value</span>)</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">//卸载组件的回调</span></span><br><span class="line">  <span class="keyword">function</span> <span class="title function_">unmount</span>(<span class="params"></span>)&#123;</span><br><span class="line">    <span class="title class_">ReactDOM</span>.<span class="title function_">unmountComponentAtNode</span>(<span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;root&#x27;</span>))</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> (</span><br><span class="line">    <span class="language-xml"><span class="tag">&lt;<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">&quot;text&quot;</span> <span class="attr">ref</span>=<span class="string">&#123;myRef&#125;/</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;<span class="name">h2</span>&gt;</span>当前求和为：&#123;count&#125;<span class="tag">&lt;/<span class="name">h2</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;<span class="name">button</span> <span class="attr">onClick</span>=<span class="string">&#123;add&#125;</span>&gt;</span>点我+1<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;<span class="name">button</span> <span class="attr">onClick</span>=<span class="string">&#123;unmount&#125;</span>&gt;</span>卸载组件<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;<span class="name">button</span> <span class="attr">onClick</span>=<span class="string">&#123;show&#125;</span>&gt;</span>点我提示数据<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">    <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line">  )</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="title class_">Demo</span></span><br></pre></td></tr></table></figure>
<h2 id="Fragment"><a href="#Fragment" class="headerlink" title="Fragment"></a>Fragment</h2><p>文档碎片</p>
<h3 id="使用-1"><a href="#使用-1" class="headerlink" title="使用"></a>使用</h3><p><code>React中的副作用操作:</code><br>或者<br><code>&lt;&gt;&lt;/&gt;</code></p>
<p>作用<br>可以不用必须有一个真实的DOM根标签了</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> <span class="title class_">React</span>, &#123; <span class="title class_">Component</span>,<span class="title class_">Fragment</span> &#125; <span class="keyword">from</span> <span class="string">&#x27;react&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="keyword">class</span> <span class="title class_">Demo</span> <span class="keyword">extends</span> <span class="title class_ inherited__">Component</span> &#123;</span><br><span class="line">  <span class="title function_">render</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> (</span><br><span class="line">      <span class="language-xml"><span class="tag">&lt;<span class="name">Fragment</span> <span class="attr">kye</span>=<span class="string">&#123;1&#125;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">&quot;text&quot;</span>/&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">&quot;text&quot;</span>/&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;/<span class="name">Fragment</span>&gt;</span></span></span><br><span class="line">    )</span><br><span class="line">  &#125;</span><br></pre></td></tr></table></figure>
<h2 id="Context"><a href="#Context" class="headerlink" title="Context"></a>Context</h2><p>上下文</p>
<p> 理解<br>一种组件间通信方式, 常用于【祖组件】与【后代组件】间通信</p>
<p>使用<br>创建Context容器对象<br>const XxxContext &#x3D; React.createContext()  </p>
<p>渲染子组时，外面包裹xxxContext.Provider, 通过value属性给后代组件传递数据：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">&lt;xxxContext.<span class="property">Provider</span> value=&#123;数据&#125;&gt;</span><br><span class="line">	子组件</span><br><span class="line">&lt;/xxxContext.<span class="property">Provider</span>&gt;</span><br><span class="line">后代组件读取数据：</span><br><span class="line">第一种方式:仅适用于类组件</span><br><span class="line"></span><br><span class="line"><span class="keyword">static</span> contextType = xxxContext  <span class="comment">// 声明接收context</span></span><br><span class="line"><span class="variable language_">this</span>.<span class="property">context</span> <span class="comment">// 读取context中的value数据</span></span><br><span class="line"></span><br><span class="line">第二种方式: 函数组件与类组件都可以</span><br><span class="line"></span><br><span class="line">&lt;xxxContext.<span class="property">Consumer</span>&gt;</span><br><span class="line">  &#123;</span><br><span class="line">    <span class="function"><span class="params">value</span> =&gt;</span> ( <span class="comment">// value就是context中的value数据</span></span><br><span class="line">      要显示的内容</span><br><span class="line">    )</span><br><span class="line">  &#125;</span><br><span class="line">&lt;/xxxContext.<span class="property">Consumer</span>&gt;</span><br></pre></td></tr></table></figure>
<p>注意<br>在应用开发中一般不用context, 一般都用它来封装react插件</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> <span class="title class_">React</span>, &#123; <span class="title class_">Component</span> &#125; <span class="keyword">from</span> <span class="string">&#x27;react&#x27;</span></span><br><span class="line"><span class="keyword">import</span> <span class="string">&#x27;./index.css&#x27;</span></span><br><span class="line"></span><br><span class="line">![<span class="number">20210619182738795.</span>png](<span class="attr">https</span>:<span class="comment">//p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/db5591474b6f460dad4b402991f89a21~tplv-k3u1fbpfcp-watermark.image?)</span></span><br><span class="line"><span class="comment">//创建Context对象</span></span><br><span class="line"><span class="keyword">const</span> <span class="title class_">MyContext</span> = <span class="title class_">React</span>.<span class="title function_">createContext</span>()</span><br><span class="line"><span class="keyword">const</span> &#123; <span class="title class_">Provider</span>, <span class="title class_">Consumer</span> &#125; = <span class="title class_">MyContext</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="keyword">class</span> <span class="title class_">A</span> <span class="keyword">extends</span> <span class="title class_ inherited__">Component</span> &#123;</span><br><span class="line"></span><br><span class="line">  state = &#123;<span class="attr">username</span>:<span class="string">&#x27;tom&#x27;</span>,<span class="attr">age</span>:<span class="number">18</span>&#125;</span><br><span class="line"></span><br><span class="line">  <span class="title function_">render</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">const</span> &#123;username,age&#125; = <span class="variable language_">this</span>.<span class="property">state</span></span><br><span class="line">    <span class="keyword">return</span> (</span><br><span class="line">      <span class="language-xml"><span class="tag">&lt;<span class="name">div</span> <span class="attr">className</span>=<span class="string">&quot;parent&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">h3</span>&gt;</span>我是A组件<span class="tag">&lt;/<span class="name">h3</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">h4</span>&gt;</span>我的用户名是:&#123;username&#125;<span class="tag">&lt;/<span class="name">h4</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">Provider</span> <span class="attr">value</span>=<span class="string">&#123;&#123;username,age&#125;&#125;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;<span class="name">B</span>/&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;/<span class="name">Provider</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line">    )</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">B</span> <span class="keyword">extends</span> <span class="title class_ inherited__">Component</span> &#123;</span><br><span class="line">  <span class="title function_">render</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> (</span><br><span class="line">      <span class="language-xml"><span class="tag">&lt;<span class="name">div</span> <span class="attr">className</span>=<span class="string">&quot;child&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">h3</span>&gt;</span>我是B组件<span class="tag">&lt;/<span class="name">h3</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">C</span>/&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line">    )</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* class C extends Component &#123;</span></span><br><span class="line"><span class="comment">  //声明接收context</span></span><br><span class="line"><span class="comment">  static contextType = MyContext</span></span><br><span class="line"><span class="comment">  render() &#123;</span></span><br><span class="line"><span class="comment">    const &#123;username,age&#125; = this.context</span></span><br><span class="line"><span class="comment">    return (</span></span><br><span class="line"><span class="comment">      &lt;div className=&quot;grand&quot;&gt;</span></span><br><span class="line"><span class="comment">        &lt;h3&gt;我是C组件&lt;/h3&gt;</span></span><br><span class="line"><span class="comment">        &lt;h4&gt;我从A组件接收到的用户名:&#123;username&#125;,年龄是&#123;age&#125;&lt;/h4&gt;</span></span><br><span class="line"><span class="comment">      &lt;/div&gt;</span></span><br><span class="line"><span class="comment">    )</span></span><br><span class="line"><span class="comment">  &#125;</span></span><br><span class="line"><span class="comment">&#125; */</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">C</span>(<span class="params"></span>)&#123;</span><br><span class="line">  <span class="keyword">return</span> (</span><br><span class="line">    <span class="language-xml"><span class="tag">&lt;<span class="name">div</span> <span class="attr">className</span>=<span class="string">&quot;grand&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;<span class="name">h3</span>&gt;</span>我是C组件<span class="tag">&lt;/<span class="name">h3</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;<span class="name">h4</span>&gt;</span>我从A组件接收到的用户名:</span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;<span class="name">Consumer</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        &#123;value =&gt; `$&#123;value.username&#125;,年龄是$&#123;value.age&#125;`&#125;</span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;/<span class="name">Consumer</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;/<span class="name">h4</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">    <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line">  )</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h1 id="组件优化"><a href="#组件优化" class="headerlink" title="组件优化"></a>组件优化</h1><h2 id="Component的问题"><a href="#Component的问题" class="headerlink" title="Component的问题"></a>Component的问题</h2><ol>
<li>只要执行setState(),即使不改变状态数据, 组件也会重新render() &#x3D;&#x3D;&gt; 效率低</li>
<li>只当前组件重新render(), 就会自动重新render子组件，纵使子组件没有用到父组件的任何数据 &#x3D;&#x3D;&gt; 效率低</li>
</ol>
<h2 id="效率高的做法"><a href="#效率高的做法" class="headerlink" title="效率高的做法"></a>效率高的做法</h2><p>只有当组件的state或props数据发生改变时才重新render()</p>
<h2 id="原因"><a href="#原因" class="headerlink" title="原因"></a>原因</h2><p><code>Component中的shouldComponentUpdate()总是返回true</code></p>
<h2 id="解决"><a href="#解决" class="headerlink" title="解决"></a>解决</h2><h3 id="办法1-重写shouldComponentUpdate-方法"><a href="#办法1-重写shouldComponentUpdate-方法" class="headerlink" title="办法1: 重写shouldComponentUpdate()方法"></a><a href=""></a><a href=""></a>办法1: 重写<code>shouldComponentUpdate()</code>方法</h3><p>比较新旧state或props数据, 如果有变化才返回true, 如果没有返回false</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="title function_">shouldComponentUpdate</span>(<span class="params">nextProps,nextState</span>)&#123;</span><br><span class="line">  <span class="comment">// console.log(this.props,this.state); //目前的props和state</span></span><br><span class="line">  <span class="comment">// console.log(nextProps,nextState); //接下要变化的目标props，目标state</span></span><br><span class="line">  <span class="keyword">return</span> !<span class="variable language_">this</span>.<span class="property">state</span>.<span class="property">carName</span> === nextState.<span class="property">carName</span></span><br><span class="line">&#125; </span><br></pre></td></tr></table></figure>
<p>办法2: 使用PureComponent<br>PureComponent重写了shouldComponentUpdate(), 只有state或props数据有变化才返回true</p>
<h1 id="注意-3"><a href="#注意-3" class="headerlink" title="注意"></a>注意</h1><blockquote>
<p><code>只是进行state和props数据的浅比较, 如果只是数据对象内部数据变了, 返回false不要直接修改state数据, 而是要产生新数据项目中一般使用PureComponent来优化</code></p>
</blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> <span class="title class_">React</span>, &#123; <span class="title class_">PureComponent</span> &#125; <span class="keyword">from</span> <span class="string">&#x27;react&#x27;</span></span><br><span class="line"><span class="keyword">import</span> <span class="string">&#x27;./index.css&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="keyword">class</span> <span class="title class_">Parent</span> <span class="keyword">extends</span> <span class="title class_ inherited__">PureComponent</span> &#123;</span><br><span class="line"></span><br><span class="line">  state = &#123;<span class="attr">carName</span>:<span class="string">&quot;奔驰c36&quot;</span>,<span class="attr">stus</span>:[<span class="string">&#x27;小张&#x27;</span>,<span class="string">&#x27;小李&#x27;</span>,<span class="string">&#x27;小王&#x27;</span>]&#125;</span><br><span class="line"></span><br><span class="line">  addStu = <span class="function">()=&gt;</span>&#123;</span><br><span class="line">    <span class="comment">/* const &#123;stus&#125; = this.state</span></span><br><span class="line"><span class="comment">    stus.unshift(&#x27;小刘&#x27;)</span></span><br><span class="line"><span class="comment">    this.setState(&#123;stus&#125;) */</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">const</span> &#123;stus&#125; = <span class="variable language_">this</span>.<span class="property">state</span></span><br><span class="line">    <span class="variable language_">this</span>.<span class="title function_">setState</span>(&#123;<span class="attr">stus</span>:[<span class="string">&#x27;小刘&#x27;</span>,...stus]&#125;)</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  changeCar = <span class="function">()=&gt;</span>&#123;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="title function_">setState</span>(&#123;<span class="attr">carName</span>:<span class="string">&#x27;迈巴赫&#x27;</span>&#125;)</span><br><span class="line"></span><br><span class="line">    <span class="comment">// const obj = this.state</span></span><br><span class="line">    <span class="comment">// obj.carName = &#x27;迈巴赫&#x27;</span></span><br><span class="line">    <span class="comment">// console.log(obj === this.state);</span></span><br><span class="line">    <span class="comment">// this.setState(obj)</span></span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">/* shouldComponentUpdate(nextProps,nextState)&#123;</span></span><br><span class="line"><span class="comment">    // console.log(this.props,this.state); //目前的props和state</span></span><br><span class="line"><span class="comment">    // console.log(nextProps,nextState); //接下要变化的目标props，目标state</span></span><br><span class="line"><span class="comment">    return !this.state.carName === nextState.carName</span></span><br><span class="line"><span class="comment">  &#125; */</span></span><br><span class="line"></span><br><span class="line">  <span class="title function_">render</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;Parent---render&#x27;</span>);</span><br><span class="line">    <span class="keyword">const</span> &#123;carName&#125; = <span class="variable language_">this</span>.<span class="property">state</span></span><br><span class="line">    <span class="keyword">return</span> (</span><br><span class="line">      <span class="language-xml"><span class="tag">&lt;<span class="name">div</span> <span class="attr">className</span>=<span class="string">&quot;parent&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">h3</span>&gt;</span>我是Parent组件<span class="tag">&lt;/<span class="name">h3</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        &#123;this.state.stus&#125;<span class="symbol">&amp;nbsp;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">span</span>&gt;</span>我的车名字是：&#123;carName&#125;<span class="tag">&lt;/<span class="name">span</span>&gt;</span><span class="tag">&lt;<span class="name">br</span>/&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">button</span> <span class="attr">onClick</span>=<span class="string">&#123;this.changeCar&#125;</span>&gt;</span>点我换车<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">button</span> <span class="attr">onClick</span>=<span class="string">&#123;this.addStu&#125;</span>&gt;</span>添加一个小刘<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">Child</span> <span class="attr">carName</span>=<span class="string">&quot;奥拓&quot;</span>/&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line">    )</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Child</span> <span class="keyword">extends</span> <span class="title class_ inherited__">PureComponent</span> &#123;</span><br><span class="line"></span><br><span class="line">  <span class="comment">/* shouldComponentUpdate(nextProps,nextState)&#123;</span></span><br><span class="line"><span class="comment">    console.log(this.props,this.state); //目前的props和state</span></span><br><span class="line"><span class="comment">    console.log(nextProps,nextState); //接下要变化的目标props，目标state</span></span><br><span class="line"><span class="comment">    return !this.props.carName === nextProps.carName</span></span><br><span class="line"><span class="comment">  &#125; */</span></span><br><span class="line"></span><br><span class="line">  <span class="title function_">render</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;Child---render&#x27;</span>);</span><br><span class="line">    <span class="keyword">return</span> (</span><br><span class="line">      <span class="language-xml"><span class="tag">&lt;<span class="name">div</span> <span class="attr">className</span>=<span class="string">&quot;child&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">h3</span>&gt;</span>我是Child组件<span class="tag">&lt;/<span class="name">h3</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">span</span>&gt;</span>我接到的车是：&#123;this.props.carName&#125;<span class="tag">&lt;/<span class="name">span</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line">    )</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h1 id="render-props"><a href="#render-props" class="headerlink" title="render props"></a>render props</h1><h2 id="如何向组件内部动态传入带内容的结构-标签"><a href="#如何向组件内部动态传入带内容的结构-标签" class="headerlink" title="如何向组件内部动态传入带内容的结构(标签)?"></a>如何向组件内部动态传入带内容的结构(标签)?</h2><p>类似于Vue中的插槽</p>
<h4 id="Vue中"><a href="#Vue中" class="headerlink" title="Vue中:"></a>Vue中:</h4><p>使用slot技术, 也就是通过组件标签体传入结构 <A><B/></A></p>
<h4 id="React中"><a href="#React中" class="headerlink" title="React中:"></a>React中:</h4><ul>
<li>使用children props: 通过组件标签体传入结构</li>
<li>使用render props: 通过组件标签属性传入结构,而且可以携带数据，一般用render函数属性</li>
</ul>
<h2 id="children-props"><a href="#children-props" class="headerlink" title="children props"></a>children props</h2><p><code>&lt;A&gt; &lt;B&gt;xxxx&lt;/B&gt; &lt;/A&gt;</code><br><strong>使用</strong></p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&#123;<span class="variable language_">this</span>.<span class="property">props</span>.<span class="property">children</span>&#125;</span><br></pre></td></tr></table></figure>
<h5 id="问题-如果B组件需要A组件内的数据-x3D-x3D-gt-做不到"><a href="#问题-如果B组件需要A组件内的数据-x3D-x3D-gt-做不到" class="headerlink" title="问题: 如果B组件需要A组件内的数据, &#x3D;&#x3D;&gt; 做不到"></a>问题: <strong>如果B组件需要A组件内的数据, &#x3D;&#x3D;&gt; 做不到</strong></h5><h2 id="render-props-1"><a href="#render-props-1" class="headerlink" title="render props"></a>render props</h2><p><code>&lt;A render=&#123;(data) =&gt; &lt;C data=&#123;data&#125;&gt;&lt;/C&gt;&#125;&gt;&lt;/A&gt;</code></p>
<h2 id="使用-2"><a href="#使用-2" class="headerlink" title="使用"></a>使用</h2><pre><code>A组件: `&#123;this.props.render(内部state数据)&#125;
C组件: 读取A组件传入的数据显示 `&#123;this.props.data&#125;
</code></pre>
<h1 id="错误边界"><a href="#错误边界" class="headerlink" title="错误边界"></a>错误边界</h1><h2 id="理解-7"><a href="#理解-7" class="headerlink" title="理解"></a>理解</h2><blockquote>
<p>错误边界(Error boundary)：用来捕获后代组件错误，渲染出备用页面</p>
</blockquote>
<h2 id="特点"><a href="#特点" class="headerlink" title="特点"></a>特点</h2><p>只能捕获后代组件生命周期产生的错误，不能捕获自己组件产生的错误和其他组件在合成事件、定时器中产生的错误</p>
<h2 id="使用方式"><a href="#使用方式" class="headerlink" title="使用方式"></a>使用方式</h2><p><code>getDerivedStateFromError配合componentDidCatch</code></p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 生命周期函数，一旦后台组件报错，就会触发</span></span><br><span class="line"><span class="keyword">static</span> <span class="title function_">getDerivedStateFromError</span>(<span class="params">error</span>) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(error);</span><br><span class="line">    <span class="comment">// 在render之前触发</span></span><br><span class="line">    <span class="comment">// 返回新的state</span></span><br><span class="line">    <span class="keyword">return</span> &#123;</span><br><span class="line">        <span class="attr">hasError</span>: <span class="literal">true</span>,</span><br><span class="line">    &#125;;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="title function_">componentDidCatch</span>(<span class="params">error, info</span>) &#123;</span><br><span class="line">    <span class="comment">// 统计页面的错误。发送请求发送到后台去</span></span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(error, info);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="示例-2"><a href="#示例-2" class="headerlink" title="示例"></a>示例</h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> <span class="title class_">React</span>, &#123; <span class="title class_">Component</span> &#125; <span class="keyword">from</span> <span class="string">&#x27;react&#x27;</span></span><br><span class="line"><span class="keyword">import</span> <span class="title class_">Child</span> <span class="keyword">from</span> <span class="string">&#x27;./Child&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="keyword">class</span> <span class="title class_">Parent</span> <span class="keyword">extends</span> <span class="title class_ inherited__">Component</span> &#123;</span><br><span class="line"></span><br><span class="line">	state = &#123;</span><br><span class="line">		<span class="attr">hasError</span>:<span class="string">&#x27;&#x27;</span> <span class="comment">// 用于标识子组件是否产生错误</span></span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="comment">//当Parent的子组件出现报错时候，会触发getDerivedStateFromError调用，并携带错误信息</span></span><br><span class="line">	<span class="keyword">static</span> <span class="title function_">getDerivedStateFromError</span>(<span class="params">error</span>)&#123;</span><br><span class="line">		<span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;@@@&#x27;</span>,error);</span><br><span class="line">		<span class="keyword">return</span> &#123;<span class="attr">hasError</span>:error&#125;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="title function_">componentDidCatch</span>(<span class="params"></span>)&#123;</span><br><span class="line">		<span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;此处统计错误，反馈给服务器，用于通知编码人员进行bug的解决&#x27;</span>);</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="title function_">render</span>(<span class="params"></span>) &#123;</span><br><span class="line">		<span class="keyword">return</span> (</span><br><span class="line">			<span class="language-xml"><span class="tag">&lt;<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">				<span class="tag">&lt;<span class="name">h2</span>&gt;</span>我是Parent组件<span class="tag">&lt;/<span class="name">h2</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">				&#123;this.state.hasError ? <span class="tag">&lt;<span class="name">h2</span>&gt;</span>当前网络不稳定，稍后再试<span class="tag">&lt;/<span class="name">h2</span>&gt;</span> : <span class="tag">&lt;<span class="name">Child</span>/&gt;</span>&#125;</span></span><br><span class="line"><span class="language-xml">			<span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line">		)</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h1 id="组件通信方式总结"><a href="#组件通信方式总结" class="headerlink" title="组件通信方式总结"></a>组件通信方式总结</h1><h2 id="组件间的关系"><a href="#组件间的关系" class="headerlink" title="组件间的关系"></a>组件间的关系</h2><ul>
<li>父子组件</li>
<li>兄弟组件（非嵌套组件）</li>
<li>祖孙组件（跨级组件）</li>
</ul>
<h2 id="几种通信方式"><a href="#几种通信方式" class="headerlink" title="几种通信方式"></a>几种通信方式</h2><ol>
<li>props：<br>(1).children props<br>(2).render props</li>
<li>消息订阅-发布：<br>pubs-sub、event等等</li>
<li>集中式管理：<br>redux、dva等等</li>
<li>Context:<br>生产者-消费者模式<h2 id="比较好的搭配方式"><a href="#比较好的搭配方式" class="headerlink" title="比较好的搭配方式"></a>比较好的搭配方式</h2></li>
</ol>
<ul>
<li>父子组件：props</li>
<li>兄弟组件：消息订阅-发布、集中式管理</li>
<li>祖孙组件(跨级组件)：消息订阅-发布、集中式管理、Context(开发用的少，封装插件用的多)</li>
</ul>
</article><div class="tag_share"><div class="post-meta__tag-list"><a class="post-meta__tags" href="/my-hexo-blog/tags/react/">react</a></div><div class="post_share"></div></div><nav class="pagination-post" id="pagination"><div class="prev-post pull-left"><a href="/my-hexo-blog/2021/03/15/vuepre/"><img class="prev-cover" src="/my-hexo-blog/img/vuepre.png" onerror="onerror=null;src='/my-hexo-blog/img/404.jpg'" alt="cover of previous post"><div class="pagination-info"><div class="label">上一篇</div><div class="prev_info">2021前端vue面试题</div></div></a></div><div class="next-post pull-right"><a href="/my-hexo-blog/2020/10/15/vue/"><img class="next-cover" src="/my-hexo-blog/img/vue.png" onerror="onerror=null;src='/my-hexo-blog/img/404.jpg'" alt="cover of next post"><div class="pagination-info"><div class="label">下一篇</div><div class="next_info">vue基础知识</div></div></a></div></nav><div class="relatedPosts"><div class="headline"><i class="fas fa-thumbs-up fa-fw"></i><span>相关推荐</span></div><div class="relatedPosts-list"><div><a href="/my-hexo-blog/2022/10/15/react%E5%8E%9F%E7%90%86/" title="react原理"><img class="cover" src="/my-hexo-blog/img/reactfiber.png" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2022-10-15</div><div class="title">react原理</div></div></a></div></div></div></div><div class="aside-content" id="aside-content"><div class="card-widget card-info"><div class="is-center"><div class="avatar-img"><img src="/my-hexo-blog/img/2.png" onerror="this.onerror=null;this.src='/my-hexo-blog/img/friend_404.gif'" alt="avatar"/></div><div class="author-info__name">william</div><div class="author-info__description"> 青山不改，绿水长流</div></div><div class="card-info-data site-data is-center"><a href="/my-hexo-blog/archives/"><div class="headline">文章</div><div class="length-num">17</div></a><a href="/my-hexo-blog/tags/"><div class="headline">标签</div><div class="length-num">13</div></a><a href="/my-hexo-blog/categories/"><div class="headline">分类</div><div class="length-num">0</div></a></div><a id="card-info-btn" target="_blank" rel="noopener" href="https://github.com/yokeney"><i class="fab fa-github"></i><span>Follow Me</span></a><div class="card-info-social-icons is-center"><a class="social-icon" href="https://github.com/yokeney" target="_blank" title="Github"><i class="fab fa-github"></i></a><a class="social-icon" href="/my-hexo-blog/965660471@qq.com" target="_blank" title="Email"><i class="fas fa-envelope"></i></a></div></div><div class="card-widget card-announcement"><div class="item-headline"><i class="fas fa-bullhorn fa-shake"></i><span>公告</span></div><div class="announcement_content">加油</div></div><div class="sticky_layout"><div class="card-widget" id="card-toc"><div class="item-headline"><i class="fas fa-stream"></i><span>目录</span><span class="toc-percentage"></span></div><div class="toc-content"><ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BB%8B%E7%BB%8D"><span class="toc-number">1.</span> <span class="toc-text">介绍</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#1-2-%E5%8E%9F%E7%94%9FJavaScript%E7%9A%84%E7%BC%BA%E7%82%B9"><span class="toc-number">2.</span> <span class="toc-text">1.2 原生JavaScript的缺点</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E3%80%90%E8%A1%A5%E5%85%85%E3%80%91%E6%A8%A1%E5%9D%97%E5%8C%96%E4%B8%8E%E7%BB%84%E4%BB%B6%E5%8C%96"><span class="toc-number">2.1.</span> <span class="toc-text">【补充】模块化与组件化</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%A8%A1%E5%9D%97"><span class="toc-number">2.1.1.</span> <span class="toc-text">模块</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#React%E7%9A%84%E7%89%B9%E7%82%B9"><span class="toc-number">2.2.</span> <span class="toc-text">React的特点</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#React%E9%AB%98%E6%95%88%E7%9A%84%E5%8E%9F%E5%9B%A0"><span class="toc-number">2.3.</span> <span class="toc-text">React高效的原因</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BD%BF%E7%94%A8JSX%E5%88%9B%E5%BB%BA%E8%99%9A%E6%8B%9FDOM"><span class="toc-number">3.</span> <span class="toc-text">使用JSX创建虚拟DOM</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E5%88%9B%E5%BB%BA%E8%99%9A%E6%8B%9FDOM%E7%9A%84%E4%B8%A4%E7%A7%8D%E6%96%B9%E5%BC%8F"><span class="toc-number"></span> <span class="toc-text">创建虚拟DOM的两种方式</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#3-1-%E7%BA%AFJS%E6%96%B9%E5%BC%8F-%E4%B8%80%E8%88%AC%E4%B8%8D%E7%94%A8"><span class="toc-number">1.</span> <span class="toc-text">3.1 纯JS方式(一般不用)</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#JSX%E6%96%B9%E5%BC%8F"><span class="toc-number">2.</span> <span class="toc-text">JSX方式</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E8%99%9A%E6%8B%9FDOM%E4%B8%8E%E7%9C%9F%E5%AE%9EDOM"><span class="toc-number"></span> <span class="toc-text">虚拟DOM与真实DOM</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#JSX%E5%85%A5%E9%97%A8"><span class="toc-number"></span> <span class="toc-text">JSX入门</span></a></li><li class="toc-item toc-level-1"><a class="toc-link"><span class="toc-number"></span> <span class="toc-text">Hello JSX!</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%80%BB%E7%BB%93"><span class="toc-number">1.</span> <span class="toc-text">总结</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E5%9F%BA%E6%9C%AC%E7%90%86%E8%A7%A3%E5%92%8C%E4%BD%BF%E7%94%A8"><span class="toc-number"></span> <span class="toc-text">基本理解和使用</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%87%BD%E6%95%B0%E5%BC%8F%E7%BB%84%E4%BB%B6"><span class="toc-number">1.</span> <span class="toc-text">函数式组件</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%A1%A5%E5%85%85%E3%80%91%E4%B8%A5%E6%A0%BC%E6%A8%A1%E5%BC%8F%E4%B8%AD%E7%9A%84this"><span class="toc-number">1.1.</span> <span class="toc-text">补充】严格模式中的this</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%B1%BB%E5%BC%8F%E7%BB%84%E4%BB%B6"><span class="toc-number">2.</span> <span class="toc-text">类式组件</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E3%80%90%E8%A1%A5%E5%85%85%E3%80%91%E5%85%B3%E4%BA%8EES6%E4%B8%AD%E7%B1%BB%E7%9A%84%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9"><span class="toc-number">2.1.</span> <span class="toc-text">【补充】关于ES6中类的注意事项</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%B3%A8%E6%84%8F"><span class="toc-number">3.</span> <span class="toc-text">注意</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E7%BB%84%E4%BB%B6%E5%AE%9E%E4%BE%8B%E7%9A%84%E4%B8%89%E5%A4%A7%E6%A0%B8%E5%BF%83%E5%B1%9E%E6%80%A71-state-%E7%8A%B6%E6%80%81"><span class="toc-number"></span> <span class="toc-text">组件实例的三大核心属性1: state 状态</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%90%86%E8%A7%A3"><span class="toc-number">1.</span> <span class="toc-text">理解</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E8%A1%A5%E5%85%85%E3%80%91%E7%B1%BB%E4%B8%AD%E6%96%B9%E6%B3%95%E7%9A%84this%E6%8C%87%E5%90%91%E9%97%AE%E9%A2%98"><span class="toc-number">1.0.1.</span> <span class="toc-text">补充】类中方法的this指向问题</span></a></li></ol></li></ol></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E7%BB%84%E4%BB%B6%E5%AE%9E%E4%BE%8B%E7%9A%84%E4%B8%89%E5%A4%A7%E6%A0%B8%E5%BF%83%E5%B1%9E%E6%80%A72-props"><span class="toc-number"></span> <span class="toc-text">组件实例的三大核心属性2: props</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%90%86%E8%A7%A3-1"><span class="toc-number">1.</span> <span class="toc-text">理解</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BD%9C%E7%94%A8"><span class="toc-number">2.</span> <span class="toc-text">作用</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97"><span class="toc-number">3.</span> <span class="toc-text">使用指南</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%86%85%E9%83%A8%E8%AF%BB%E5%8F%96%E6%9F%90%E4%B8%AA%E5%B1%9E%E6%80%A7%E5%80%BC"><span class="toc-number">3.1.</span> <span class="toc-text">内部读取某个属性值</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%89%A9%E5%B1%95%E5%B1%9E%E6%80%A7-%E5%B0%86%E5%AF%B9%E8%B1%A1%E7%9A%84%E6%89%80%E6%9C%89%E5%B1%9E%E6%80%A7%E9%80%9A%E8%BF%87props%E4%BC%A0%E9%80%92%EF%BC%88%E6%89%B9%E9%87%8F%E4%BC%A0%E9%80%92%E6%A0%87%E7%AD%BE%E5%B1%9E%E6%80%A7%EF%BC%89"><span class="toc-number">3.2.</span> <span class="toc-text">扩展属性: 将对象的所有属性通过props传递（批量传递标签属性）</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E3%80%90%E8%A1%A5%E5%85%85%E3%80%91%E5%B1%95%E5%BC%80%E8%BF%90%E7%AE%97%E7%AC%A6"><span class="toc-number">3.2.1.</span> <span class="toc-text">【补充】展开运算符</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%AF%B9props%E4%B8%AD%E7%9A%84%E5%B1%9E%E6%80%A7%E5%80%BC%E8%BF%9B%E8%A1%8C%E7%B1%BB%E5%9E%8B%E9%99%90%E5%88%B6%E5%92%8C%E5%BF%85%E8%A6%81%E6%80%A7%E9%99%90%E5%88%B6"><span class="toc-number">3.3.</span> <span class="toc-text">对props中的属性值进行类型限制和必要性限制</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%BB%98%E8%AE%A4%E5%B1%9E%E6%80%A7%E5%80%BC"><span class="toc-number">3.4.</span> <span class="toc-text">默认属性值</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%BB%84%E4%BB%B6%E7%B1%BB%E7%9A%84%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0"><span class="toc-number">3.5.</span> <span class="toc-text">组件类的构造函数</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%87%BD%E6%95%B0%E5%BC%8F%E7%BB%84%E4%BB%B6%E4%BD%BF%E7%94%A8props"><span class="toc-number">4.</span> <span class="toc-text">函数式组件使用props</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#refs%E4%B8%8E%E4%BA%8B%E4%BB%B6%E5%A4%84%E7%90%86"><span class="toc-number"></span> <span class="toc-text">refs与事件处理</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%90%86%E8%A7%A3-2"><span class="toc-number">1.</span> <span class="toc-text">理解</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%BC%96%E7%A0%81"><span class="toc-number">2.</span> <span class="toc-text">编码</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%AD%97%E7%AC%A6%E4%B8%B2%E5%BD%A2%E5%BC%8F%E7%9A%84ref%EF%BC%88%E6%96%B0%E7%89%88%E6%9C%AC%E4%B8%8D%E6%8E%A8%E8%8D%90%E4%BD%BF%E7%94%A8%E4%BA%86%EF%BC%89"><span class="toc-number">2.1.</span> <span class="toc-text">字符串形式的ref（新版本不推荐使用了）</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E7%A4%BA%E4%BE%8B"><span class="toc-number">2.1.1.</span> <span class="toc-text">示例</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%9B%9E%E8%B0%83%E5%BD%A2%E5%BC%8F%E7%9A%84ref"><span class="toc-number">2.2.</span> <span class="toc-text">回调形式的ref</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E7%A4%BA%E4%BE%8B-1"><span class="toc-number">2.2.1.</span> <span class="toc-text">示例</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%9B%9E%E8%B0%83%E6%89%A7%E8%A1%8C%E6%AC%A1%E6%95%B0"><span class="toc-number">2.2.2.</span> <span class="toc-text">回调执行次数</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#createRef%E5%88%9B%E5%BB%BAref%E5%AE%B9%E5%99%A8"><span class="toc-number">2.3.</span> <span class="toc-text">createRef创建ref容器</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E4%BD%BF%E7%94%A8"><span class="toc-number">2.3.1.</span> <span class="toc-text">使用</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#React%E4%B8%AD%E7%9A%84%E4%BA%8B%E4%BB%B6%E5%A4%84%E7%90%86"><span class="toc-number">2.4.</span> <span class="toc-text">React中的事件处理</span></a></li></ol></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E6%94%B6%E9%9B%86%E8%A1%A8%E5%8D%95%E6%95%B0%E6%8D%AE"><span class="toc-number"></span> <span class="toc-text">收集表单数据</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%90%86%E8%A7%A3-3"><span class="toc-number">1.</span> <span class="toc-text">理解</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E9%9D%9E%E5%8F%97%E6%8E%A7%E7%BB%84%E4%BB%B6"><span class="toc-number">2.</span> <span class="toc-text">非受控组件</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%8F%97%E6%8E%A7%E7%BB%84%E4%BB%B6"><span class="toc-number">3.</span> <span class="toc-text">受控组件</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E9%AB%98%E9%98%B6%E5%87%BD%E6%95%B0%E4%B8%8E%E5%87%BD%E6%95%B0%E7%9A%84%E6%9F%AF%E9%87%8C%E5%8C%96"><span class="toc-number"></span> <span class="toc-text">高阶函数与函数的柯里化</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%AB%98%E9%98%B6%E5%87%BD%E6%95%B0"><span class="toc-number">0.1.</span> <span class="toc-text">高阶函数</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%87%BD%E6%95%B0%E7%9A%84%E6%9F%AF%E9%87%8C%E5%8C%96"><span class="toc-number">1.</span> <span class="toc-text">函数的柯里化</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E7%BB%84%E4%BB%B6%E7%9A%84%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F"><span class="toc-number"></span> <span class="toc-text">组件的生命周期</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%90%86%E8%A7%A3-4"><span class="toc-number">1.</span> <span class="toc-text">理解</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%BC%95%E5%85%A5%E6%A1%88%E4%BE%8B"><span class="toc-number">2.</span> <span class="toc-text">引入案例</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E7%9A%84%E4%B8%89%E4%B8%AA%E9%98%B6%E6%AE%B5%EF%BC%88%E6%97%A7%EF%BC%89"><span class="toc-number">3.</span> <span class="toc-text">生命周期的三个阶段（旧）</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%8D%B8%E8%BD%BD%E7%BB%84%E4%BB%B6"><span class="toc-number">3.1.</span> <span class="toc-text">卸载组件</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E7%9A%84%E4%B8%89%E4%B8%AA%E9%98%B6%E6%AE%B5%EF%BC%88%E6%96%B0%EF%BC%89"><span class="toc-number">4.</span> <span class="toc-text">生命周期的三个阶段（新）</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%9B%B4%E6%96%B0%E9%98%B6%E6%AE%B5"><span class="toc-number">4.0.1.</span> <span class="toc-text">更新阶段</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E9%87%8D%E8%A6%81%E7%9A%84%E5%8B%BE%E5%AD%90"><span class="toc-number">5.</span> <span class="toc-text">重要的勾子</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%8D%B3%E5%B0%86%E5%BA%9F%E5%BC%83%E7%9A%84%E5%8B%BE%E5%AD%90"><span class="toc-number">6.</span> <span class="toc-text">即将废弃的勾子</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E8%99%9A%E6%8B%9FDOM%E4%B8%8EDOM-Diffing%E7%AE%97%E6%B3%95"><span class="toc-number"></span> <span class="toc-text">虚拟DOM与DOM Diffing算法</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%9F%BA%E6%9C%AC%E5%8E%9F%E7%90%86%E5%9B%BE"><span class="toc-number">1.</span> <span class="toc-text">基本原理图</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%85%B3%E4%BA%8Ekey%E7%9A%84%E7%BB%8F%E5%85%B8%E9%9D%A2%E8%AF%95%E9%A2%98"><span class="toc-number">2.</span> <span class="toc-text">关于key的经典面试题</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E7%94%A8index%E4%BD%9C%E4%B8%BAkey%E5%8F%AF%E8%83%BD%E4%BC%9A%E5%BC%95%E5%8F%91%E7%9A%84%E9%97%AE%E9%A2%98"><span class="toc-number">2.0.1.</span> <span class="toc-text">用index作为key可能会引发的问题</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#SPA%E7%9A%84%E7%90%86%E8%A7%A3"><span class="toc-number">3.</span> <span class="toc-text">SPA的理解</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E8%B7%AF%E7%94%B1%E7%9A%84%E7%90%86%E8%A7%A3"><span class="toc-number">4.</span> <span class="toc-text">路由的理解</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%BB%80%E4%B9%88%E6%98%AF%E8%B7%AF%E7%94%B1"><span class="toc-number">4.1.</span> <span class="toc-text">什么是路由?</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%B7%AF%E7%94%B1%E5%88%86%E7%B1%BB"><span class="toc-number">4.2.</span> <span class="toc-text">路由分类</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%90%8E%E7%AB%AF%E8%B7%AF%E7%94%B1"><span class="toc-number">4.2.1.</span> <span class="toc-text">后端路由</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%89%8D%E7%AB%AF%E8%B7%AF%E7%94%B1"><span class="toc-number">4.2.2.</span> <span class="toc-text">前端路由</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#react-router-dom-%E7%9A%84%E7%90%86%E8%A7%A3"><span class="toc-number">5.</span> <span class="toc-text">react-router-dom 的理解</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#react-router-dom%E7%9B%B8%E5%85%B3API"><span class="toc-number"></span> <span class="toc-text">react-router-dom相关API</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%86%85%E7%BD%AE%E7%BB%84%E4%BB%B6"><span class="toc-number">1.</span> <span class="toc-text">内置组件</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%85%B6%E5%AE%83"><span class="toc-number">2.</span> <span class="toc-text">其它</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E5%9F%BA%E6%9C%AC%E8%B7%AF%E7%94%B1%E4%BD%BF%E7%94%A8"><span class="toc-number"></span> <span class="toc-text">基本路由使用</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%95%88%E6%9E%9C"><span class="toc-number">1.</span> <span class="toc-text">效果</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%87%86%E5%A4%87"><span class="toc-number">2.</span> <span class="toc-text">准备</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E8%B7%AF%E7%94%B1%E7%9A%84%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8"><span class="toc-number">3.</span> <span class="toc-text">路由的基本使用</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%AE%9E%E7%8E%B0"><span class="toc-number">4.</span> <span class="toc-text">实现</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#index-js"><span class="toc-number">4.1.</span> <span class="toc-text">index.js</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#App-jsx"><span class="toc-number">4.2.</span> <span class="toc-text">App.jsx</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E8%B7%AF%E7%94%B1%E7%BB%84%E4%BB%B6%E4%B8%8E%E4%B8%80%E8%88%AC%E7%BB%84%E4%BB%B6%E7%9A%84%E5%8C%BA%E5%88%AB"><span class="toc-number">5.</span> <span class="toc-text">路由组件与一般组件的区别</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Switch%E7%9A%84%E4%BD%BF%E7%94%A8"><span class="toc-number">6.</span> <span class="toc-text">Switch的使用</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E8%A7%A3%E5%86%B3%E5%A4%9A%E7%BA%A7%E8%B7%AF%E5%BE%84%E5%88%B7%E6%96%B0%E9%A1%B5%E9%9D%A2%E6%A0%B7%E5%BC%8F%E4%B8%A2%E5%A4%B1%E7%9A%84%E9%97%AE%E9%A2%98"><span class="toc-number">7.</span> <span class="toc-text">解决多级路径刷新页面样式丢失的问题</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E8%B7%AF%E7%94%B1%E7%9A%84%E4%B8%A5%E6%A0%BC%E5%8C%B9%E9%85%8D%E4%B8%8E%E6%A8%A1%E7%B3%8A%E5%8C%B9%E9%85%8D"><span class="toc-number">8.</span> <span class="toc-text">路由的严格匹配与模糊匹配</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Redirect%E7%9A%84%E4%BD%BF%E7%94%A8-%E3%80%90%E9%87%8D%E5%AE%9A%E5%90%91%E3%80%91"><span class="toc-number">9.</span> <span class="toc-text">Redirect的使用 【重定向】</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E5%B5%8C%E5%A5%97%E8%B7%AF%E7%94%B1%E4%BD%BF%E7%94%A8"><span class="toc-number"></span> <span class="toc-text">嵌套路由使用</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%95%88%E6%9E%9C-1"><span class="toc-number">1.</span> <span class="toc-text">效果</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%B3%A8%E6%84%8F-1"><span class="toc-number">2.</span> <span class="toc-text">注意</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%AE%9E%E7%8E%B0-1"><span class="toc-number">3.</span> <span class="toc-text">实现</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Home-x2F-index-jsx"><span class="toc-number">3.1.</span> <span class="toc-text">Home&#x2F;index.jsx</span></a></li></ol></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E5%90%91%E8%B7%AF%E7%94%B1%E7%BB%84%E4%BB%B6%E4%BC%A0%E9%80%92%E5%8F%82%E6%95%B0%E6%95%B0%E6%8D%AE"><span class="toc-number"></span> <span class="toc-text">向路由组件传递参数数据</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%95%88%E6%9E%9C-2"><span class="toc-number">1.</span> <span class="toc-text">效果</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%85%B7%E4%BD%93%E6%96%B9%E6%B3%95"><span class="toc-number">2.</span> <span class="toc-text">具体方法</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#Message-x2F-index-jsx"><span class="toc-number">2.0.1.</span> <span class="toc-text">Message&#x2F;index.jsx</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#Detail-x2F-index-jsx"><span class="toc-number">2.0.2.</span> <span class="toc-text">Detail&#x2F;index.jsx</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#Message-x2F-index-jsx-1"><span class="toc-number">2.0.3.</span> <span class="toc-text">Message&#x2F;index.jsx</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#Detail-x2F-index-jsx-1"><span class="toc-number">2.0.4.</span> <span class="toc-text">Detail&#x2F;index.jsx</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%A4%9A%E7%A7%8D%E8%B7%AF%E7%94%B1%E8%B7%B3%E8%BD%AC%E6%96%B9%E5%BC%8F"><span class="toc-number">2.1.</span> <span class="toc-text">多种路由跳转方式</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E7%BC%96%E7%A8%8B%E5%BC%8F%E8%B7%AF%E7%94%B1%E5%AF%BC%E8%88%AA"><span class="toc-number">2.1.1.</span> <span class="toc-text">编程式路由导航</span></a></li></ol></li></ol></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E6%B3%A8%E6%84%8F-2"><span class="toc-number"></span> <span class="toc-text">注意</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#BrowserRouter%E4%B8%8EHashRouter%E7%9A%84%E5%8C%BA%E5%88%AB"><span class="toc-number">1.</span> <span class="toc-text">BrowserRouter与HashRouter的区别</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#redux%E7%90%86%E8%A7%A3"><span class="toc-number"></span> <span class="toc-text">redux理解</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%9B%B8%E5%85%B3%E6%96%87%E6%A1%A3"><span class="toc-number">1.</span> <span class="toc-text"> 相关文档</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#redux%E6%98%AF%E4%BB%80%E4%B9%88"><span class="toc-number">2.</span> <span class="toc-text">redux是什么</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BB%80%E4%B9%88%E6%83%85%E5%86%B5%E4%B8%8B%E9%9C%80%E8%A6%81%E4%BD%BF%E7%94%A8redux"><span class="toc-number">3.</span> <span class="toc-text">什么情况下需要使用redux</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#redux%E5%B7%A5%E4%BD%9C%E6%B5%81%E7%A8%8B"><span class="toc-number">4.</span> <span class="toc-text">redux工作流程</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#redux%E7%9A%84%E4%B8%89%E4%B8%AA%E6%A0%B8%E5%BF%83%E6%A6%82%E5%BF%B5"><span class="toc-number"></span> <span class="toc-text">redux的三个核心概念</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#action"><span class="toc-number">1.</span> <span class="toc-text">action</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#reducer"><span class="toc-number">2.</span> <span class="toc-text">reducer</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#store"><span class="toc-number">3.</span> <span class="toc-text">store</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#API"><span class="toc-number"></span> <span class="toc-text">API</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#createStore"><span class="toc-number">0.0.1.</span> <span class="toc-text">createStore()</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#store%E5%AF%B9%E8%B1%A1"><span class="toc-number">0.0.2.</span> <span class="toc-text">store对象</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#combineReducers"><span class="toc-number">0.0.3.</span> <span class="toc-text">combineReducers()</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E4%BD%BF%E7%94%A8redux%E7%BC%96%E5%86%99%E5%BA%94%E7%94%A8"><span class="toc-number">0.0.4.</span> <span class="toc-text">使用redux编写应用</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%AE%9E%E7%8E%B0-2"><span class="toc-number">1.</span> <span class="toc-text">实现</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#redux-x2F-store-js"><span class="toc-number">1.1.</span> <span class="toc-text">redux&#x2F;store.js</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#redux-x2F-count-reducer-js"><span class="toc-number">1.2.</span> <span class="toc-text">redux&#x2F;count_reducer.js</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#redux-x2F-count-action-js"><span class="toc-number">1.3.</span> <span class="toc-text">redux&#x2F;count_action.js</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#redux-x2F-constant-js"><span class="toc-number">1.4.</span> <span class="toc-text">redux&#x2F;constant.js</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Count-x2F-index-jsx"><span class="toc-number">1.5.</span> <span class="toc-text">Count&#x2F;index.jsx</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#index-js-1"><span class="toc-number">1.6.</span> <span class="toc-text">index.js</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#store-js%EF%BC%9A"><span class="toc-number">1.7.</span> <span class="toc-text">store.js：</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#count-reducer-js%EF%BC%9A"><span class="toc-number">1.7.1.</span> <span class="toc-text">count_reducer.js：</span></a></li></ol></li></ol></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#redux%E5%BC%82%E6%AD%A5%E7%BC%96%E7%A8%8B"><span class="toc-number"></span> <span class="toc-text">redux异步编程</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%90%86%E8%A7%A3-5"><span class="toc-number">1.</span> <span class="toc-text">理解</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BD%BF%E7%94%A8%E5%BC%82%E6%AD%A5%E4%B8%AD%E9%97%B4%E4%BB%B6"><span class="toc-number">2.</span> <span class="toc-text">使用异步中间件</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#count-action-js"><span class="toc-number">2.1.</span> <span class="toc-text">count_action.js</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#store-js"><span class="toc-number">2.2.</span> <span class="toc-text">store.js</span></a></li></ol></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#react-redux"><span class="toc-number"></span> <span class="toc-text">react-redux</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%90%86%E8%A7%A3-6"><span class="toc-number">1.</span> <span class="toc-text">理解</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#react-redux%E5%B0%86%E6%89%80%E6%9C%89%E7%BB%84%E4%BB%B6%E5%88%86%E6%88%90%E4%B8%A4%E5%A4%A7%E7%B1%BB"><span class="toc-number">2.</span> <span class="toc-text">react-redux将所有组件分成两大类</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8"><span class="toc-number">3.</span> <span class="toc-text">基本使用</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%AE%89%E8%A3%85"><span class="toc-number">3.1.</span> <span class="toc-text">安装</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#components-x2F-Count-x2F-index-jsx"><span class="toc-number">3.2.</span> <span class="toc-text">components&#x2F;Count&#x2F;index.jsx</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#containers-x2F-Count-x2F-index-jsx"><span class="toc-number">3.3.</span> <span class="toc-text">containers&#x2F;Count&#x2F;index.jsx</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#App-jsx-1"><span class="toc-number">3.4.</span> <span class="toc-text">App.jsx</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BC%98%E5%8C%96"><span class="toc-number">4.</span> <span class="toc-text">优化</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%BC%98%E5%8C%961-%E7%AE%80%E5%86%99mapDispatchToProps"><span class="toc-number">4.1.</span> <span class="toc-text">优化1 简写mapDispatchToProps</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#index-js-2"><span class="toc-number">4.1.1.</span> <span class="toc-text">index.js</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%BC%98%E5%8C%963-%E6%95%B4%E5%90%88UI%E7%BB%84%E4%BB%B6%E5%92%8C%E5%AE%B9%E5%99%A8%E7%BB%84%E4%BB%B6"><span class="toc-number">4.2.</span> <span class="toc-text">优化3 整合UI组件和容器组件</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#containers-x2F-Count-x2F-index-jsx-1"><span class="toc-number">4.2.1.</span> <span class="toc-text">containers&#x2F;Count&#x2F;index.jsx</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#store-js-1"><span class="toc-number">4.3.</span> <span class="toc-text">store.js</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%BA%AF%E5%87%BD%E6%95%B0"><span class="toc-number">4.4.</span> <span class="toc-text">纯函数</span></a></li></ol></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E6%9C%80%E7%BB%88%E7%89%88"><span class="toc-number"></span> <span class="toc-text">最终版</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#containers-x2F-Count-x2F-index-jsx-2"><span class="toc-number">1.</span> <span class="toc-text">containers&#x2F;Count&#x2F;index.jsx</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#containers-x2F-Person-x2F-index-jsx"><span class="toc-number">2.</span> <span class="toc-text">containers&#x2F;Person&#x2F;index.jsx</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#redux-x2F-actions-x2F-count-js"><span class="toc-number">3.</span> <span class="toc-text">redux&#x2F;actions&#x2F;count.js</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#redux-x2F-action-x2F-person-js"><span class="toc-number">4.</span> <span class="toc-text">redux&#x2F;action&#x2F;person.js</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#redux-x2F-reducers-x2F-count-js"><span class="toc-number">5.</span> <span class="toc-text">redux&#x2F;reducers&#x2F;count.js</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#redux-x2F-reducers-x2F-person-js"><span class="toc-number">6.</span> <span class="toc-text">redux&#x2F;reducers&#x2F;person.js</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#redux-x2F-reducers-x2F-index-js"><span class="toc-number">7.</span> <span class="toc-text">redux&#x2F;reducers&#x2F;index.js</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#redux-x2F-constant-js-1"><span class="toc-number">8.</span> <span class="toc-text">redux&#x2F;constant.js</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#redux-x2F-store-js-1"><span class="toc-number">9.</span> <span class="toc-text">redux&#x2F;store.js</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#App-jsx-2"><span class="toc-number">10.</span> <span class="toc-text">App.jsx</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#index-js-3"><span class="toc-number">11.</span> <span class="toc-text">index.js</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E3%80%90React%E3%80%91%E6%8B%93%E5%B1%95"><span class="toc-number"></span> <span class="toc-text">【React】拓展</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#setState"><span class="toc-number">1.</span> <span class="toc-text">setState</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%AF%B9%E8%B1%A1%E5%BC%8F"><span class="toc-number">2.</span> <span class="toc-text">对象式</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%87%BD%E6%95%B0%E5%BC%8F"><span class="toc-number">3.</span> <span class="toc-text">函数式</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E8%B7%AF%E7%94%B1%E7%BB%84%E4%BB%B6%E7%9A%84%E6%87%92%E5%8A%A0%E8%BD%BD-lazyLoad"><span class="toc-number"></span> <span class="toc-text">路由组件的懒加载 lazyLoad</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#Hooks"><span class="toc-number"></span> <span class="toc-text">Hooks</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#Fragment"><span class="toc-number">1.</span> <span class="toc-text">Fragment</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%BD%BF%E7%94%A8-1"><span class="toc-number">1.1.</span> <span class="toc-text">使用</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Context"><span class="toc-number">2.</span> <span class="toc-text">Context</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E7%BB%84%E4%BB%B6%E4%BC%98%E5%8C%96"><span class="toc-number"></span> <span class="toc-text">组件优化</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#Component%E7%9A%84%E9%97%AE%E9%A2%98"><span class="toc-number">1.</span> <span class="toc-text">Component的问题</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%95%88%E7%8E%87%E9%AB%98%E7%9A%84%E5%81%9A%E6%B3%95"><span class="toc-number">2.</span> <span class="toc-text">效率高的做法</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%8E%9F%E5%9B%A0"><span class="toc-number">3.</span> <span class="toc-text">原因</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E8%A7%A3%E5%86%B3"><span class="toc-number">4.</span> <span class="toc-text">解决</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%8A%9E%E6%B3%951-%E9%87%8D%E5%86%99shouldComponentUpdate-%E6%96%B9%E6%B3%95"><span class="toc-number">4.1.</span> <span class="toc-text">办法1: 重写shouldComponentUpdate()方法</span></a></li></ol></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E6%B3%A8%E6%84%8F-3"><span class="toc-number"></span> <span class="toc-text">注意</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#render-props"><span class="toc-number"></span> <span class="toc-text">render props</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%A6%82%E4%BD%95%E5%90%91%E7%BB%84%E4%BB%B6%E5%86%85%E9%83%A8%E5%8A%A8%E6%80%81%E4%BC%A0%E5%85%A5%E5%B8%A6%E5%86%85%E5%AE%B9%E7%9A%84%E7%BB%93%E6%9E%84-%E6%A0%87%E7%AD%BE"><span class="toc-number">1.</span> <span class="toc-text">如何向组件内部动态传入带内容的结构(标签)?</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#Vue%E4%B8%AD"><span class="toc-number">1.0.1.</span> <span class="toc-text">Vue中:</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#React%E4%B8%AD"><span class="toc-number">1.0.2.</span> <span class="toc-text">React中:</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#children-props"><span class="toc-number">2.</span> <span class="toc-text">children props</span></a><ol class="toc-child"><li class="toc-item toc-level-5"><a class="toc-link" href="#%E9%97%AE%E9%A2%98-%E5%A6%82%E6%9E%9CB%E7%BB%84%E4%BB%B6%E9%9C%80%E8%A6%81A%E7%BB%84%E4%BB%B6%E5%86%85%E7%9A%84%E6%95%B0%E6%8D%AE-x3D-x3D-gt-%E5%81%9A%E4%B8%8D%E5%88%B0"><span class="toc-number">2.0.0.1.</span> <span class="toc-text">问题: 如果B组件需要A组件内的数据, &#x3D;&#x3D;&gt; 做不到</span></a></li></ol></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#render-props-1"><span class="toc-number">3.</span> <span class="toc-text">render props</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BD%BF%E7%94%A8-2"><span class="toc-number">4.</span> <span class="toc-text">使用</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E9%94%99%E8%AF%AF%E8%BE%B9%E7%95%8C"><span class="toc-number"></span> <span class="toc-text">错误边界</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%90%86%E8%A7%A3-7"><span class="toc-number">1.</span> <span class="toc-text">理解</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%89%B9%E7%82%B9"><span class="toc-number">2.</span> <span class="toc-text">特点</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BD%BF%E7%94%A8%E6%96%B9%E5%BC%8F"><span class="toc-number">3.</span> <span class="toc-text">使用方式</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%A4%BA%E4%BE%8B-2"><span class="toc-number">4.</span> <span class="toc-text">示例</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E7%BB%84%E4%BB%B6%E9%80%9A%E4%BF%A1%E6%96%B9%E5%BC%8F%E6%80%BB%E7%BB%93"><span class="toc-number"></span> <span class="toc-text">组件通信方式总结</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%BB%84%E4%BB%B6%E9%97%B4%E7%9A%84%E5%85%B3%E7%B3%BB"><span class="toc-number">1.</span> <span class="toc-text">组件间的关系</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%87%A0%E7%A7%8D%E9%80%9A%E4%BF%A1%E6%96%B9%E5%BC%8F"><span class="toc-number">2.</span> <span class="toc-text">几种通信方式</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%AF%94%E8%BE%83%E5%A5%BD%E7%9A%84%E6%90%AD%E9%85%8D%E6%96%B9%E5%BC%8F"><span class="toc-number">3.</span> <span class="toc-text">比较好的搭配方式</span></a></li></ol></div></div><div class="card-widget card-recent-post"><div class="item-headline"><i class="fas fa-history"></i><span>最新文章</span></div><div class="aside-list"><div class="aside-list-item"><a class="thumbnail" href="/my-hexo-blog/2023/05/26/VUE3%E9%9B%86%E6%88%90%E4%BC%81%E4%B8%9A%E7%BA%A7%E5%90%8E%E5%8F%B0%E9%80%9A%E7%94%A8%E8%A7%84%E8%8C%83%E6%A8%A1%E7%89%88/" title="VUE3集成企业级后台通用规范模版"><img src="/my-hexo-blog/img/1.png" onerror="this.onerror=null;this.src='/my-hexo-blog/img/404.jpg'" alt="VUE3集成企业级后台通用规范模版"/></a><div class="content"><a class="title" href="/my-hexo-blog/2023/05/26/VUE3%E9%9B%86%E6%88%90%E4%BC%81%E4%B8%9A%E7%BA%A7%E5%90%8E%E5%8F%B0%E9%80%9A%E7%94%A8%E8%A7%84%E8%8C%83%E6%A8%A1%E7%89%88/" title="VUE3集成企业级后台通用规范模版">VUE3集成企业级后台通用规范模版</a><time datetime="2023-05-26T13:17:48.000Z" title="发表于 2023-05-26 21:17:48">2023-05-26</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/my-hexo-blog/2023/04/24/%E6%B2%A1%E7%9C%8B%E8%BF%99%E7%AF%87%E6%96%87%E7%AB%A0%E4%B9%8B%E5%89%8D%E5%8E%9F%E6%9D%A5%E6%88%91%E5%AF%B9react18%E4%B8%80%E7%9F%A5%E5%8D%8A%E8%A7%A3/" title="没看这篇文章之前原来我对react18一知半解"><img src="/my-hexo-blog/img/react.png" onerror="this.onerror=null;this.src='/my-hexo-blog/img/404.jpg'" alt="没看这篇文章之前原来我对react18一知半解"/></a><div class="content"><a class="title" href="/my-hexo-blog/2023/04/24/%E6%B2%A1%E7%9C%8B%E8%BF%99%E7%AF%87%E6%96%87%E7%AB%A0%E4%B9%8B%E5%89%8D%E5%8E%9F%E6%9D%A5%E6%88%91%E5%AF%B9react18%E4%B8%80%E7%9F%A5%E5%8D%8A%E8%A7%A3/" title="没看这篇文章之前原来我对react18一知半解">没看这篇文章之前原来我对react18一知半解</a><time datetime="2023-04-24T09:11:02.000Z" title="发表于 2023-04-24 17:11:02">2023-04-24</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/my-hexo-blog/2023/04/24/%E5%8F%B2%E4%B8%8A%E6%9C%80%E5%85%A8Vue3%E6%80%BB%E7%BB%93/" title="史上最全Vue3总结"><img src="/my-hexo-blog/img/1.png" onerror="this.onerror=null;this.src='/my-hexo-blog/img/404.jpg'" alt="史上最全Vue3总结"/></a><div class="content"><a class="title" href="/my-hexo-blog/2023/04/24/%E5%8F%B2%E4%B8%8A%E6%9C%80%E5%85%A8Vue3%E6%80%BB%E7%BB%93/" title="史上最全Vue3总结">史上最全Vue3总结</a><time datetime="2023-04-24T09:01:19.000Z" title="发表于 2023-04-24 17:01:19">2023-04-24</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/my-hexo-blog/2023/04/24/%E4%B8%8EReact18%E7%9A%84%E5%8C%BA%E5%88%AB%E6%B7%B1%E5%BA%A6%E8%A7%A3%E6%9E%90/" title="Vue与React18的区别深度解析"><img src="/my-hexo-blog/img/vue_vs-react.png" onerror="this.onerror=null;this.src='/my-hexo-blog/img/404.jpg'" alt="Vue与React18的区别深度解析"/></a><div class="content"><a class="title" href="/my-hexo-blog/2023/04/24/%E4%B8%8EReact18%E7%9A%84%E5%8C%BA%E5%88%AB%E6%B7%B1%E5%BA%A6%E8%A7%A3%E6%9E%90/" title="Vue与React18的区别深度解析">Vue与React18的区别深度解析</a><time datetime="2023-04-24T08:39:32.000Z" title="发表于 2023-04-24 16:39:32">2023-04-24</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/my-hexo-blog/2022/10/25/%E6%89%8B%E6%8A%8A%E6%89%8B%E5%B8%A6%E4%BD%A0%E5%86%99%E4%B8%80%E4%B8%AAbabel/" title="手把手教你写babel插件"><img src="/my-hexo-blog/img/babel.webp" onerror="this.onerror=null;this.src='/my-hexo-blog/img/404.jpg'" alt="手把手教你写babel插件"/></a><div class="content"><a class="title" href="/my-hexo-blog/2022/10/25/%E6%89%8B%E6%8A%8A%E6%89%8B%E5%B8%A6%E4%BD%A0%E5%86%99%E4%B8%80%E4%B8%AAbabel/" title="手把手教你写babel插件">手把手教你写babel插件</a><time datetime="2022-10-25T01:10:14.000Z" title="发表于 2022-10-25 09:10:14">2022-10-25</time></div></div></div></div></div></div></main><footer id="footer" style="background-image: url('/my-hexo-blog/img/1.png')"><div id="footer-wrap"><div class="copyright">&copy;2018 - 2023 By william</div><div class="footer_custom_text">关山难越，谁悲失路之人</div></div></footer></div><div id="rightside"><div id="rightside-config-hide"><button id="readmode" type="button" title="阅读模式"><i class="fas fa-book-open"></i></button><button id="darkmode" type="button" title="浅色和深色模式转换"><i class="fas fa-adjust"></i></button><button id="hide-aside-btn" type="button" title="单栏和双栏切换"><i class="fas fa-arrows-alt-h"></i></button></div><div id="rightside-config-show"><button id="rightside_config" type="button" title="设置"><i class="fas fa-cog fa-spin"></i></button><button class="close" id="mobile-toc-button" type="button" title="目录"><i class="fas fa-list-ul"></i></button><button id="go-up" type="button" title="回到顶部"><i class="fas fa-arrow-up"></i></button></div></div><div id="local-search"><div class="search-dialog"><nav class="search-nav"><span class="search-dialog-title">搜索</span><span id="loading-status"></span><button class="search-close-button"><i class="fas fa-times"></i></button></nav><div class="is-center" id="loading-database"><i class="fas fa-spinner fa-pulse"></i><span>  数据库加载中</span></div><div class="search-wrap"><div id="local-search-input"><div class="local-search-box"><input class="local-search-box--input" placeholder="搜索文章" type="text"/></div></div><hr/><div id="local-search-results"></div></div></div><div id="search-mask"></div></div><div><script src="/my-hexo-blog/js/utils.js"></script><script src="/my-hexo-blog/js/main.js"></script><script src="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox.umd.min.js"></script><script src="/my-hexo-blog/js/search/local-search.js"></script><div class="js-pjax"></div><div class="aplayer no-destroy" data-id="22712173" data-server="netease" data-mini="true" data-type="song" data-autoplay="false" data-lrcType="-1"> </div><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.css" media="print" onload="this.media='all'"><script src="https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.js"></script><script src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/metingjs/dist/Meting.min.js"></script><script async data-pjax src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script></div></body></html>